-
-
Notifications
You must be signed in to change notification settings - Fork 9.6k
[Security] Native support for 2FA #28868
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
Comments
I also would like to see native support for this, especially since 2FA is becoming a requirement more and more these days. |
Thanks for opening this issue. I also think having a native support for 2FA would be great. Concerning the graph and the state of "partially authenticated" (with "IS_AUTHENTICATED_2FA_IN_PROGRESS"), I would like to discuss one problem we could face. For some of our application, we store some authorization logic in database. The role does not suffice to check some right, and we do not store any role into the token. In voter, we check that the token contains some User (and we assume there that the user is fully authenticated) and, then, we perform the verification of authorization. I just fear that, in a state "partially authenticated", the line You could argue that we should also check that the token contains the role If it is not too much complicated, I think it would be reasonable to avoid a state "semi authenticated" which might open security issues in application based upon symfony. |
Hum... Diving into the api, I show the method If I am alone to see a security issue in the state "partially authenticated", I must admit that we should rewrite all our Voters using this method. We should just ensure that, in the state "partially authenticated", the method |
The issue you're describing is a bit the same as when using the remember me feature ( I'm not completely sure if 2FA is part of the authentication or authorization process. If part of the authentication (I prefer this), using roles may be confusing to determine if the user is fully authenticated or in progress. If part of the authorization, it may allow to have some highly secured areas where 2FA is required and others where it's not. Usage of roles is then convenient. Maybe adding a kind of "identity confidence" level in the token can solve this and be used also in the remember me feature? |
The issue is not exactly the same. IS_AUTHENTICATED_REMEMBERED is considered as authenticated. But then, some parts of the app my require being fully authenticated (not trusting remember-me for sensitive things). |
@stof I don't really agree. In both cases what we want to do is setting a minimum level of trust in the current user identity. When the user I'm starting to believe that what we need is to store a level of identity trust in the token (for instance a simple integer), and use it to protect some routes (maybe using the access controls and/or setting minimum values for firewalls). This may be used for both |
@quentinus95 |
Thanks for the clarification. Do you think having having a kind of identity confidence level stored inside the token (for instance) could make things simpler regarding the issues we are facing for implementing 2FA properly? |
@quentinus95 As I understand, you want to have a higher level of confidence in authentication for some action's controller, and allow the user to reach other action. But my use case is to replace completely the username/password authentication by 2FA, without having to rewrite dozens of Voter to check that "the user is fully authenticated" (at least, some user will use 2FA and other not, which will make things more complicated). In the way I consider the job of a Authentication Provider (but maybe I am wrong), the authentication provider should authenticate completely, without having a "middle" state where the user "is-authenticated-but-not-fully" which is not obvious to understand. In my opinion, the user is authenticated, or not. But I am happy to discuss this. |
Actually, some action's controller may be the whole application. You could consider a form login gives you 50 points of confidence, and an additional 2FA form can give you 25 additional points. If you want to enable 2FA on your app, you may add an access control in your security.yml to ask for a minimum of 75 points for the path This kind of system is interesting because you may have many different chained authentication forms depending on the minimum level of trust required, as well as reducing the level in some situations (for instance if you stay inactive during a long period). I have the feeling that "fully authenticated" does not mean a lot and is against any evolution in the security level we define in our apps. Being able to define a level ( |
Just a side-note, we could take some inspiration from the https://github.com/apereo/cas. They have a very robust implementation built around spring & pac4j. One thing I'd like to bring in is the notion of multi-factor authentication (mfa) rather than 2-factor authentication. We should allow for flexibility in a sense that authentication providers could be possibly chained. It's worth reading through their docs this https://apereo.github.io/cas/6.0.x/mfa/Configuring-Multifactor-Authentication.html @quentinus95 although the score model could be seen as an improvement to authorization, it's is not a requirement for multi-factor authentication imo. could be also added to an existing guard-protected setup. let's focus on the authentication. @stof An intermediate permission attribute or an alternative will be required in order to control access to some user's protected resources (phone number, email address, screen personalisation data), while the user is in the process of authentication. @scheb uses a Another thing that scheb does, is decoration of configured authentication providers to intercept the authentication process. I believe this was necessary because of lack of flexibility in a firewall itself. We could add a MultiFactorListener to the chain similary to A few more ideas
I'm happy work on a POC as soon as we have these basic low-level integrations agreed. |
Yes, exactly, I can confirm that. It is doing it to intercept any authentication provider. It is used to warp the authenticated token with the If there would be a better way doing it, I'd be glad using it. Manipulating DIC with a decorator feels a bit hacky. |
The work on 2FA should be part of updating Symfony Security as a whole, and is tracked in #30914. I like the discussions here so I'll recommend we keep it open and link it from there. |
@fmonts it would not work if 2FA is not enabled for all users nor if SMS or emails are used as a second factor. |
If not enabled you leave the field blank. True for email, SMS are a very different protocol, I think it's expensive and quite outdated today, also every gateway has its own different API, so I don't think it's worth to build a native support in Symfony for SMS... |
@fmonts I don't think Symfony should support a specific SMS provider, but it should provide a way to register a custom "challenger" to add support for it. Forcing the user to have the 2FA field on the login for is too opinionated. Moreover, for FIDO/WebAuthn there is no 2FA field at all. |
@Nek- it is related, but that issues serves as a major list (more a milestone than an issue). Having discussions in more targetted issues is better imho. I would say as soon as we build support for this in core, which would be very nice btw, we should build an MFA implementation instead of just 2FA. We'll then be more flexible. I think it would make the most sense if MFA is fully part of the authentication phase. Meaning a not fully authenticated user shouldn't be able to enter the authorization phase (thus voters and such). This means it won't break any existing apps. I was thinking about maybe there is way to have a |
@wouterj actually I believe MFA/2FA could be used with the same mecanisms as for sudo mode or remember me. It would be interesting to have a way to quantify the level of trust we give to an identity. When the user is authenticated, there is no more concept of "fully authenticated" user. We just increase the level of trust. The same way we use roles for authorization, we could ask for a minimum level of trust to access resources. It would depend on your current level (determined by the way you authenticated, for instance This would allow to support sudo mode (i.e. re-asking the user password could increase (temporary) the level of trust), remember me (i.e. the level of trust is lower than when using username & password) and MFA (each new factor increases the level of trust). It could even allow for MFA authentication only (for instance authentication using a temporary code recieved by email or SMS). It seems very concenient that all these concepts are grouped together, as they are all part of the same idea: quantify how much we trust the identity of the authenticated used (a little bit like when you ask people to sign your PGP key). |
What you described seems to me as "level of assurance", referenced in OIDC spec as Authentication Context Class reference.
|
Thank you for this suggestion. |
Yes |
Yes. |
Yes! |
I am working with Symfony and Api-Platform using jwt authentication in split cookies. My customers want a 2FA functionality. So it would be good if this feature will be added. |
@remoteclient using https://github.com/scheb/2fa/ is the recommended solution to add 2FA in Symfony. |
Let's close as we do have support via scheb/2fa. @scheb does an awesome job and the bundle is even compatible with the next security system. |
Note that I believe we should find the "hacky" bits that scheb/2fa needs to work with Symfony and see if Symfony can improve. I've talked with @scheb about this in the past year and he contributed most improvements himself. I believe the only left-over improvement is adding "some knowledge of authentication factors (sudo mode)", which is covered in #39308 as well. I'm welcoming any help here |
Description
2FA shoud be natively supported by the security component, to get more interoperability between projects and support from the community (as well as external bundles provinding specific 2FA features, e.g. U2F).
There are bundles providing support, but most of them are either outdated or not providing a simple, low level API (with a seamless integration in the Symfony security component). They also do not provide the same guaranteed support as Symfony does.
Example
The latest version of
scheb/two-factor-bundle
provides a good proof of concept, but the API is too restrictive, high level and some of the validation / handling code for the 2FA is a duplicate from existing code in the security component.Some of the main low levels features which would be useful:
I guess a new role equivalent to IS_AUTHENTICATED_ANONYMOUSLY would be required, like in the process described here: https://github.com/scheb/two-factor-bundle/blob/master/Resources/doc/index.md#the-authentication-process
[Edit] See this comment for a proposal to unify sudo mode, MFA and remember me:
The text was updated successfully, but these errors were encountered: