Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Configure multiple lexik_jwt_auth #707

Open
Taluu opened this issue Jan 9, 2020 · 8 comments
Open

Configure multiple lexik_jwt_auth #707

Taluu opened this issue Jan 9, 2020 · 8 comments

Comments

@Taluu
Copy link

Taluu commented Jan 9, 2020

Kinda linked to #504, but here goes ;

It could be great to be able to set multiple configurations for the config name, by using a prototype in the config. As does doctrine for example to be able to configure multiple entity managers / connections, so we can inject the jwt authentication we need.

e.g

lexik_jwt_authentication:
    api:
        secret_key: 'secret_key'
        token_ttl: 3600
        encoder:
            signature_algorithm: HS256

    other:
        secret_key: 'secret_key'
        token_ttl: 60
        encoder:
            signature_algorithm: HS256
@fl0cke
Copy link

fl0cke commented Mar 24, 2020

Would be really nice to have this feature 👍

@badrutdinovrr
Copy link

As soon as Symphony lacks multiple bundle instances support and it seems @lexikteam is not interested in this issue, here is a workaround.

First of all, DI gives us ability to override any part of the bundle. A hint how to make many authenticators is given here

We have to define another authenticator on our own using existing configuration.
Given the application with client and admin api (^/api/client and ^/api/admin respectively), we have to add another guard (config/security.yaml):

security:
    firewalls:
...
        admin:
            pattern: ^/api/admin
            anonymous: false
            lazy: true
            provider: jwt

            guard:
                authenticators:
                    - app.jwt_admin_authenticator
...

Here we use another authenticator, whose config looks like (config/services.yaml):

....
app.jwt_admin_jws_key_loader:
        parent: lexik_jwt_authentication.key_loader.raw
        arguments:
            index_0: '%env(JWT_ADMIN_SECRET_KEY)%'

    app.jwt_admin_jws_provider:
        parent: lexik_jwt_authentication.jws_provider.lcobucci
        arguments:
            index_0: '@app.jwt_admin_jws_key_loader'
            index_2: '%lexik_jwt_authentication.encoder.signature_algorithm%'

    app.jwt_admin_encoder:
        parent: lexik_jwt_authentication.encoder.lcobucci
        arguments:
            index_0: '@app.jwt_admin_jws_provider'

    app.jwt_admin_manager:
        parent: lexik_jwt_authentication.jwt_manager
        arguments:
            index_0: '@app.jwt_admin_encoder'
            index_2: 'systemUserId'
        calls:
            - [setUserIdentityField, ['systemUserId']]

    app.jwt_admin_authenticator:
        parent: lexik_jwt_authentication.jwt_token_authenticator
        arguments:
            index_0: '@app.jwt_admin_manager'
....

So, you can just assemble your own JWT authenticator using existing components. Unfortunately this approach can cause to tight coupling with bundle structure since you have to know how to build necessary objects.

@TonyBogdanov
Copy link

+1 for this!

In my setup I'm using JWT authentication for regular users, but I'm also using Google Cloud Pub/Sub with push endpoints, which I obviously need to firewall somehow. Google supports authenticating its requests with a JWT token generated for a service account, so all I need to do is verify that token against the service account.

The bundle works nicely to achieve this, the only problem is I can't use separate key pairs for Pub/Sub and my regular users, which is a disastrous security hole.

I'll have to explore @badrutdinovrr's custom authenticator workaround.

@chalasr
Copy link
Collaborator

chalasr commented Mar 7, 2021

With the new Symfony authenticator-based security system, we are probably going to move most of the config to per-firewall configuration (with a lexik_jwt: ~ configurable authenticator). Would that fit your use cases?

@TonyBogdanov
Copy link

With the new Symfony authenticator-based security system, we are probably going to move most of the config to per-firewall configuration (with a lexik_jwt: ~ configurable authenticator). Would that fit your use cases?

Yes, that would actually be the best solution. I've been looking into the new approach and it really does simplify things a lot! Too bad it'll be mostly used in Symfony 6.0, which in my mind, is to be widely adopted in at least a couple of years...

@Aweptimum
Copy link

With the new Symfony authenticator-based security system, we are probably going to move most of the config to per-firewall configuration (with a lexik_jwt: ~ configurable authenticator). Would that fit your use cases?

Yes +1 to this, just wanted to add my support. Thank you for this awesome bundle, though!

@fd6130
Copy link

fd6130 commented Sep 17, 2021

With the new Symfony authenticator-based security system, we are probably going to move most of the config to per-firewall configuration (with a lexik_jwt: ~ configurable authenticator). Would that fit your use cases?

How can we reuse to the other firewall if we put the config under it? Assume we want api1 and api2 using the same configuration (and also for the login part):

api2:
    lexik_jwt: ~

api1:
   lexik_jwt: ~

chalasr added a commit that referenced this issue Dec 8, 2021
…h a set of keys (alexandre-daubois)

This PR was merged into the 2.x branch.

Discussion
----------

Add support of multiple public keys to verify tokens with a set of keys

It may be convenient to use multiple public keys to verify token signature when using RS algorithm. It would allow to verify tokens coming from different providers.

Somehow related to #707

Commits
-------

88ce60e feat: add support of multiple public keys to verify tokens with a set of keys
@mbabker
Copy link
Contributor

mbabker commented May 11, 2022

Something else that will help massively with supporting multiple authenticators is re-working the AuthenticationSuccessHandler behavior. Right now the onAuthenticationSuccess() method passes only the user object into its handleAuthenticationSuccess() method, and the user plus the generated JWT are all that are available in the AuthenticationSuccessEvent. It'd be nice if more of the security information (firewall and token) were available without having to pull data from other services which relies on order of operations not changing inside Symfony's AuthenticatorManager class. I looked at this a year ago in JWTRefreshTokenBundle and IMO having to dig around for those two bits of info makes using the AuthenticationSuccessEvent a bit more complicated than it needs to be (especially considering that the two events the authenticator manager dispatches around the success handler both include the token and use the firewall specific event dispatcher).

Plus, if the settings do move from the top-level bundle config to the authenticator config (or, similar to the way I handled the authenticator in the refresh token bundle, supporting "global" settings through the bundle config and overriding config values on a per-firewall basis), it becomes more important that the services used in the authentication flow become aware of the final firewall specific configuration.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

8 participants