LexikJWTAuthenticationBundle
LexikJWTAuthenticationBundle copied to clipboard
Using the bundle with token created somewhere else
My company is intending to use http://www.keycloak.org/ to generate JWTs for applications that need it. I'm trying to use this bundle for the guard it provides, which I guess can check the signature against a public key. I skipped the configuration step where you provide the keys for the moment, and created the following security config:
security:
# https://symfony.com/doc/current/book/security.html#where-do-users-come-from-user-providers
providers:
in_memory: { memory: ~ }
firewalls:
dev:
pattern: ^/(_(profiler|wdt)|css|images|js)/
security: false
api:
stateless: true
guard:
authenticators:
- lexik_jwt_authentication.jwt_token_authenticator
access_control:
- { path: ^/, roles: IS_AUTHENTICATED_FULLY }
The app crashes
Environment variable not found: "JWT_PRIVATE_KEY_PATH".
This sounds wrong, because I'm not trying to generate a token here, since I didn't provide any credentials.
I can see it trying to load a JWSProviderInterface
implementation at some point. This interface looks like it should maybe be split into 2 interfaces, so that the private key would no longer be depended on:
https://github.com/lexik/LexikJWTAuthenticationBundle/blob/ddfd184c8dd2f56b0b01bc5731dc84c9c9396701/Services/JWSProvider/JWSProviderInterface.php#L10-L30
It would be great if the JWT generation was optional. Not sure if I'm making sense, these are my first steps with JWT.
What do you think? Does it make sense to use this bundle in my case, or is it not worth the hassle?
Hmm nevermind, flex added that env in a config file for me, so although I thought I hadn't configured anything, I actually did. Will close if I manage to use the bundle without a private key.
Or rather, I'll reopen if I can't use the bundle, but I just stopped getting 500s :)
The use case seems legit to me. I'm not totally sure it's fully supported, but if it is not, supporting it should not require much work (at worst some validation to remove from JWSProviderInterface implems). Please keep me informed
I'll keep you posted in both cases then, thanks a lot for caring!
Second hurdle, but I believe it's not the fault of this bundle: https://github.com/symfony/symfony/issues/24877
Third hurdle, I need to use the client_credentials
. To achieve that I need to switch to https://github.com/FriendsOfSymfony/FOSOAuthServerBundle (I don't need the server part though). That's what I understand when reading https://github.com/api-platform/core/pull/982
It's a bit scary though, there does not seem to be much activity on this bundle...
I think I'm going to stick with Lexik and try to make it work anyway, not quite sure how yet.
I finally managed to authenticate!
I had to pretend to be in username password mode and use clientid
as user_identity_field
.
Here is my user class:
<?php
namespace App\Application\Security;
use Lexik\Bundle\JWTAuthenticationBundle\Security\User\JWTUser;
use Lexik\Bundle\JWTAuthenticationBundle\Security\User\JWTUserInterface;
final class User extends JWTUser implements JWTUserInterface
{
public static function createFromPayload($username, array $payload): self
{
return new self(
$username,
$payload['resource_access'][$username]['roles']
);
}
}
Nice use case, well done!
Thanks!
This use case is very interesting.
It will be great if the bundle could support that. For example through a list of trusted issuers (iss
claim + associated public/shared keys for token verification).
@ WDYT?
I assumed the token was verified with the public key I provided but didn't actually check that. And you are proposing to have several of them 🤔 ? That's interesting indeed!
That's it. At the moment the bundle uses the key defined in the configuration to verify the token signatures. If the bundle is able to support trusted third parties, this means it has to manage several public/shared keys (maybe other parameters) to be able to verify tokens issued by those parties.
I see several use cases:
- The bundle issues and verifies its own tokens (current behavior)
- The bundle verifies its own tokens and tokens from third parties
- The bundle only checks tokens from third parties.
- The bundle only issues tokens that are checked by another application.
These use cases show that the bundle can be decoupled and can either act as an ID provider, a security firewall or both. A kind of lightweight OAuth2/OIDC server.
Should I reopen this issue? Or should you create a new one for clarity?
Sounds good to me, let's discuss it here
From what @Spomky says, I think what is needed is :
- the ability to have several public keys
- the ability to have 2 parts of the bundle that work without waking up the other, which means some interfaces like
JWSProviderInterface
probably need to be split into 2 interfaces, and same should probably go for the implementations. Corresponding services should be loaded only when needed
Hi everyone, I am also very interested in this, especially with @Spomky proposal:
For example through a list of trusted issuers (iss claim + associated public/shared keys for token verification).
Is anyone currently working on this? I would love to help in any way if possible. Please let me know. Great bundle by the way.
Hi @ermalmino,
Yes I am working on it and I will add this feature on my custom encoder. But the feature is not yet ready. Hoping I can merge it by the end of the month.
I've created this demo project that allow to verify a user logged in on firebase https://github.com/hpatoio/api-platform-jwt-firebase
any news about this use case ?
This would be nice!
I finally managed to authenticate!
I had to pretend to be in username password mode and use
clientid
asuser_identity_field
.Here is my user class:
<?php namespace App\Application\Security; use Lexik\Bundle\JWTAuthenticationBundle\Security\User\JWTUser; use Lexik\Bundle\JWTAuthenticationBundle\Security\User\JWTUserInterface; final class User extends JWTUser implements JWTUserInterface { public static function createFromPayload($username, array $payload): self { return new self( $username, $payload['resource_access'][$username]['roles'] ); } }
Please, I would like to see how you implement this. I am having the same issue.
Error: Class App\Security\JWTUser contains 5 abstract methods and must therefore be declared abstract or implement the remaining methods (Symfony\Component\Security\Core\User\UserInterface::getRoles, Symfony\Component\Security\Core\User\UserInterface::getPassword, Symfony\Component\Security\Core\User\UserInterface::getSalt, ...)
and when I added the abstract methods, I encountered
Cannot autowire service "App\Security\JWTUser": argument "$username" of method "__construct()" is type-hinted "string", you should configure its value explicitly.