-
-
Notifications
You must be signed in to change notification settings - Fork 9.6k
[Security] [RememberMe] Add support for parallel requests doing remember-me re-authentication #41175
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
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good to me. Only the comment regarding the hardcoded 60 seconds is something that could be considered. But that is not a reason to not merge this from my point of view.
src/Symfony/Bridge/Doctrine/Security/RememberMe/DoctrineTokenProvider.php
Outdated
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please make use of return types for brand-new methods. Also, can you please update the component's changelog?
src/Symfony/Component/Security/Core/Authentication/RememberMe/TokenVerifierInterface.php
Outdated
Show resolved
Hide resolved
src/Symfony/Bridge/Doctrine/Security/RememberMe/DoctrineTokenProvider.php
Outdated
Show resolved
Hide resolved
d7e6541
to
5344272
Compare
I updated the implementation to make I could remove the DoctrineTokenProvider implementation though if you rather avoid having a default fix which is slightly hackish (I fully documented the implementation now so it's hopefully clearer what is going on). I also added a CacheTokenVerifier implementation which is the ideal one I would configure in prod, but I guess this can not be enabled by default as it requires a configured cache? I'm not sure what the baseline is here. Edit: I'm also not sure why Psalm fails, it complains about some code I did not change, not sure if I should apply those fixes or not. |
fyi: I don't have time for a detailed review today, it's on my list for tomorrow |
src/Symfony/Bundle/SecurityBundle/DependencyInjection/Security/Factory/RememberMeFactory.php
Outdated
Show resolved
Hide resolved
src/Symfony/Component/Security/Core/Authentication/RememberMe/CacheTokenVerifier.php
Outdated
Show resolved
Hide resolved
src/Symfony/Component/Security/Core/Authentication/RememberMe/CacheTokenVerifier.php
Outdated
Show resolved
Hide resolved
src/Symfony/Component/Security/Http/RememberMe/PersistentRememberMeHandler.php
Outdated
Show resolved
Hide resolved
src/Symfony/Component/Security/Http/RememberMe/PersistentRememberMeHandler.php
Outdated
Show resolved
Hide resolved
Thanks for the hints @chalasr - I hope my implementation in 8c1d0cc is correct - I'm not entirely sure if the nested null on invalid ref will work here https://github.com/symfony/symfony/pull/41175/files#diff-c790b1d460cd1f019b3eefa9c0322710d078dbadd510dbb1ee631c4c668e0dbcR323-R328 I'm hoping it would set the cache ref to null if the cache service gets deleted by the pass, which would then mark the whole verifier service invalid as the cache arg is not nullable, turning the whole verifier into a null itself. @wouterj I think we can argue either way.. but if the current implementation works I'd say why not ship a fix by default and save people from having to find out about this issue before they can configure the verifier service. |
@Seldaek |
You will probably need a DI tag to collect the cache-based token verifier definitions and remove them from the compiler pass. |
Yes but injecting null for $cache means the CacheTokenVerifier definition becomes invalid, so I believe it will automatically be removed/nulled, and the RememberMeAuthenticator receives null as verifier. I tested with this and it seems to work as expected, I get an services:
App\Test: # this would be the verifier service
arguments:
- '@?cache.foo'
App\Test2: # and this the authenticator
arguments:
- '@?App\Test' |
In your example
Here is a reproducer https://github.com/chalasr/repro-null-on-invalid (clone, run |
Nope, App\Test2 accepts a nullable App\Test in my example, because that's what the PersistentRememberMeHandler accepts https://github.com/symfony/symfony/pull/41175/files#diff-5128596229172c9c8dc0dda0e9846231169b9d239c65366cb13ce6ffc2a913daR39 (a nullable TokenVerifierInterface). Anyway if you want I can tweak the compiler pass to explicitly nullify the service, but to me it does not seem necessary. Edit: You got the example backwards I now realize, App\Test should get a non-nullable cache pool, because that's also what CacheTokenVerifier expects. |
Ok got it, thanks! |
src/Symfony/Bundle/SecurityBundle/DependencyInjection/Security/Factory/RememberMeFactory.php
Outdated
Show resolved
Hide resolved
That's for 5.4, or 5.3? |
I was hoping for 5.3 but that's just my opinion ;) |
So it won't be backported to 4.4? |
@zerkms no, Symfony only fixes bugs in already released versions. I'm a bit divided on 5.3/5.4. On one hand, it's a nice and mostly hidden "bug fix" that fits nicely with the other remember me changes in 5.3. On the other hand, the change is fully BC and thus has no reason (other than another 6 months waiting) to bypass the feature-freeze deadline (unless I'm missing something). |
@wouterj it says "3 year support for bugs and security fixes." at https://symfony.com/releases for 4.4 🤷 |
@zerkms It won't be backported because the patch is not compatible with the 4.4 implementation of the remember-me feature. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is fine-tuning the 5.3 rewrite of the remember-me feature, while removing a long standing limitation of that feature, so I think it's fine for 5.3.
@chalasr then
should be reworded, to be like "3 year support for some bugs and security fixes"? If a bug is reported against v4.4 (which also is affected) would it be fixed independently? |
If someone is able to submit a valid fix for 4.4, we could probably accept it. |
Tests seem to be broken. |
Thank you @Seldaek. |
This is a possible implementation to gather feedback mostly..
TokenVerifierInterface
naming is kinda bad perhaps.. But my goal would be to merge it in TokenProviderInterface for 6.0 so it's not so important. Not sure if/how to best indicate this in terms of deprecation notices.Anyway wondering if this would be an acceptable implementation (ideally in an application I would probably override the new methods from DoctrineTokenProvider to something like this which is less of a hack and does expiration properly:
If you think it'd be fine to require optionally the cache inside DoctrineTokenProvider to enable this feature instead of the hackish way I did it, that'd be ok for me too.
The current
DoctrineTokenProvider
implementation ofTokenVerifierInterface
relies on the lucky fact that series are generated usingbase64_encode(random_bytes(64))
which always ends in the==
padding of base64, so that allowed me to store an alternative token value temporarily by replacing==
with_
.Alternative implementation options:
DoctrineTokenProvider
and do a proper implementation (as shown above) that wayDoctrineTokenProvider
and let users who care implement this themselves.token_verifier
option that could be configured on thefirewall->remember_me
key so you can pass an implementation if needed, and possibly ship a default one using cache that could be autoconfigured@chalasr @wouterj sorry for the long description but in the hope of getting this included in 5.3.0, if you can provide guidance I will happily work on this further tomorrow to try and wrap it up ASAP.