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

[Security] Support loading UserBadge directly from accessToken #48285

Merged
merged 1 commit into from Nov 24, 2022

Conversation

Jeroeny
Copy link
Contributor

@Jeroeny Jeroeny commented Nov 22, 2022

Q A
Branch? 6.2
Bug fix? no
New feature? yes
Deprecations? no
License MIT
Doc PR -

I attended @welcoMattic 's nice talk at SymfonyCon Paris last week, after which we and @wouterj discussed the way tokens need to be parsed to obtain a userIdentifier. With JWT tokens, there is usually no need to make a call to a database to instantiate a User object. Because the token is signed, we can guarantee the user details inside it are valid. See example code: https://github.com/welcoMattic/painless-authentication-with-access-token/blob/main/slides/slides.md#62-jwthandler

In Symfony's authentication system, retrieving the userIdentifier and the User is a two-step process. However with both the userIdentifier and the User object coming from the token, we either have to parse the token twice or store it in memory.

I think this can be improved by allowing a single step to go from $token (string) -> parsed token (implementation specific) -> User object.

The suggested change in this PR is probably not yet the way to go, but I'd like to hear from the Security contributers if they have any ideas.

@carsonbot
Copy link

carsonbot commented Nov 22, 2022

Hey!

Thanks for your PR. You are targeting branch "6.2" but it seems your PR description refers to branch "6.3".
Could you update the PR description or change target branch? This helps core maintainers a lot.

Cheers!

Carsonbot

@stof
Copy link
Member

stof commented Nov 22, 2022

The proposal here makes the UserProvider responsible for implementing all the token validation. To me, this risks encouraging bad implementations because the UserProvider is currently responsible for none of the validation.

I'd rather have a specific interface to be implemented by the AccessTokenHandler to return a UserBadge directly instead of only the identifier (or something like that).
Note that it might not even be a special interface. We could have getUserIdentifierFrom(string $accessToken): string|UserBadge allowing to return a UserBadge directly for the advanced case.

@chalasr
Copy link
Member

chalasr commented Nov 22, 2022

Note that it might not even be a special interface. We could have getUserIdentifierFrom(string $accessToken): string|UserBadge allowing to return a UserBadge directly for the advanced case.

Looks sensible to me.

@Jeroeny
Copy link
Contributor Author

Jeroeny commented Nov 22, 2022

I've changed it to use the string|UserBadge return types instead.

@stof
Copy link
Member

stof commented Nov 22, 2022

Widening the return type of the interface will be a BC break for consumers of the interface though. So if we delay that to 6.3, we'll have to use a separate method

@Jeroeny
Copy link
Contributor Author

Jeroeny commented Nov 22, 2022

@stof I thought a string returntype in implementations of the interface would be covariant with string|UserBadge?

@wouterj
Copy link
Member

wouterj commented Nov 22, 2022

@Jeroeny yes, it's OK for implementations, but consumers have to take care of another type when calling the method - which would be a BC break.

@stof
Copy link
Member

stof commented Nov 22, 2022

@Jeroeny the BC break concerns consumers, not implementors. For implementors, the covariance rule indeed makes it BC. Btw, that's the reason why a child class is not allowed to widen a return type as it would break consumers.

And also the main consumer is in the core and will be updated, any decorator class is both an implementation and a consumer and will be impacted by the widened type.

@chalasr
Copy link
Member

chalasr commented Nov 22, 2022

Since some on-going implementations already need this, I'd be fine merging this on 6.2 as a feature-freeze adjustment.

@Jeroeny
Copy link
Contributor Author

Jeroeny commented Nov 22, 2022

Ah or course, for consumers. Allowing it in 6.2 would be cool.

Copy link
Member

@chalasr chalasr left a comment

For 6.2

Copy link
Member

@dunglas dunglas left a comment

👍 for 6.2 too.

@Jeroeny
Copy link
Contributor Author

Jeroeny commented Nov 23, 2022

Should private readonly UserProviderInterface $userProvider of AccessTokenAuthenticator become nullable? What UserProviderInterface would you inject when you are already retrieving the UserBadge from the AccessTokenHandlerInterface ?

@chalasr
Copy link
Member

chalasr commented Nov 23, 2022

None indeed, can you make the change in this PR?

@Jeroeny
Copy link
Contributor Author

Jeroeny commented Nov 23, 2022

@chalasr Added, I have 2 open questions about the consequences, see comments :).

fabpot
fabpot approved these changes Nov 24, 2022
Copy link
Member

@wouterj wouterj left a comment

It took some iterations, but I like this solution. Thanks for initiating this and all the quick responses, @Jeroeny!

@nicolas-grekas nicolas-grekas modified the milestones: 6.3, 6.2 Nov 24, 2022
@nicolas-grekas
Copy link
Member

nicolas-grekas commented Nov 24, 2022

Thank you @Jeroeny.

@nicolas-grekas nicolas-grekas merged commit 19940ff into symfony:6.2 Nov 24, 2022
5 of 8 checks passed
@Jeroeny
Copy link
Contributor Author

Jeroeny commented Nov 24, 2022

Thanks all 👍

vincentchalamon added a commit to vincentchalamon/symfony that referenced this pull request Nov 24, 2022
@Jeroeny Jeroeny deleted the auth branch Nov 24, 2022
vincentchalamon added a commit to vincentchalamon/symfony that referenced this pull request Nov 25, 2022
@fabpot fabpot mentioned this pull request Nov 25, 2022
vincentchalamon added a commit to vincentchalamon/symfony that referenced this pull request Nov 25, 2022
vincentchalamon added a commit to vincentchalamon/symfony that referenced this pull request Nov 26, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

9 participants