Skip to content
This repository has been archived by the owner on Dec 2, 2021. It is now read-only.

Integrating with Symfony 4 and FOSUserBundle #183

Closed
AmbushIV opened this issue Nov 24, 2018 · 15 comments
Closed

Integrating with Symfony 4 and FOSUserBundle #183

AmbushIV opened this issue Nov 24, 2018 · 15 comments

Comments

@AmbushIV
Copy link

Hey there Scheb, after a few days I decided I should make an issue here to ask for some clarifications. I consider the steps for the integration of your package to not be so clear when it comes to Symfony 4.

What I have done so far:

  1. Added the appropriate variables to my User entity (with getters and setters).
  2. Used Symfony Flex for the scheb_two_factor configuration files.
  3. Since I want to use google authenticator (I did setup google in my configuration file 'enabled: true').
  4. Went to my security file and added the path ^/2fa;

Now... I have already updated my user registration process in order for them to have a secret key generated and I also generated the QR codes in the backend (even though I am going to use React as a frontend engine).

What I am missing is this:

  1. How do I use your twig template in a controller?
  2. How do I get to check the code the user gets from google authenticator?

When I go to localhost:8000/2fa I get the following error: "A Token was not found in the TokenStorage".

I am kind of a newbie to Symfony and backend overall and I am either missing steps or the documentation is not very beginner friendly. I intend to make a tutorial for beginners once I get it up and running with React (since there are no tutorials regarding this).

Thank you for your time (I would also love to talk with you in private chat if you want to).

@scheb
Copy link
Owner

scheb commented Nov 25, 2018

Would you please post your security.yaml configuration for further debugging?

How do I use your twig template in a controller?

The controller (which is part of the bundle) and is configured behind the /2fa route will render it.

How do I get to check the code the user gets from google authenticator?

The bundle does that automatically. You have added the Google Authenticator TwoFactorInterface to your entity. This interface will be used by the bundle to determine, if there's a two-factor authentication method enabled for that user. This is the case when isGoogleAuthenticatorEnabled() returns true and getGoogleAuthenticatorSecret() returns a secret value. If so, the bundle will force the user to pass two-factor authentication by redirecting to the /2fa route, which is then showing the form. When the user enters a valid authentication code, it'll let the user pass.

When I go to localhost:8000/2fa I get the following error: "A Token was not found in the TokenStorage".

I'd guess you're not in the two-factor authentication stage at that point. The bundle would redirect you to that route, when it needs to ask for an authentication code.

@AmbushIV
Copy link
Author

Hey Scheb, thank you for such fast reply.

I am going to share with you my whole project as I think it will be hard to troubleshoot with a single file.

Here is my git repository: https://github.com/AmbushIV/arb2

As far as I understand since I am building a simple API only backend I need to check after a succesful login if the google authenticator is enabled via isGoogleAuthenticatorEnabled and then use getGoogleAuthenticatorSecret to get "a secret value" (i guess this is the code the user has to enter via google authenticator") that I have to send to my frontend. As I don't know how 2fa works in the backend I wonder how does the backend know which is the correct code the user entered (since these change frequently).

Thank you for your time!

@wh1pp3rz
Copy link

wh1pp3rz commented Nov 26, 2018

Hey @scheb I'm also trying to setup this bundle to work with fos-user-bundle and google authenticator but I'm getting errors. I've followed the default setup and I can confirm fos-user-bundle is creating an instance of core UsernamePasswordToken. The error I get is the following: User is not in a two-factor authentication process. This is after I enter my username/password and is redirected to /2fa

Here's what's in my security yaml:

firewalls:
    admin:
            pattern:   ^/admin
            anonymous: ~
            provider: fos_userbundle
            form_login:
                login_path: /admin/login
                check_path: /admin/login_check
                default_target_path: /admin
            logout:
                path: /admin/logout
                target: /admin/login
            two_factor:
                auth_form_path: 2fa_login
                check_path: 2fa_login_check

@wh1pp3rz
Copy link

Never mind I figured it out, I needed to configure my routes to be /admin/2fa and /admin/2fa_check

@wh1pp3rz
Copy link

@scheb I have one small issue, everything is working fine except the cancel button on the verification form, it redirects me back to the /2fa verification page instead of doing the logout and take me back to my login page. When I'm successfully logged in, the logout button works fine.

@scheb
Copy link
Owner

scheb commented Nov 26, 2018

@wh1pp3rz We had a similar issue in #168. Is your cancel link pointing to /admin/logout? You should also configure IS_AUTHENTICATED_ANONYMOUSLY for the logout path in access_control and make sure this rule is listed first (since access_control is applied in that order).

Compare: https://github.com/scheb/two-factor-app/blob/master/config/packages/security.yaml

@wh1pp3rz
Copy link

@scheb I did all that but still I have the issue. Here's my logout route as defined in config/routes.yaml:

admin_logout:
    path: /admin/logout

Here's my firewall config:

firewalls:
    admin:
            pattern:   ^/admin
            anonymous: ~
            provider: admin_user_provider
            guard:
                authenticators:
                    - App\Security\Admin\LoginFormAuthenticator
            remember_me:
                secret:   '%kernel.secret%'
                lifetime: 7200 # 2 hours in seconds
                path:     /
            logout:
                path: admin_logout
                target: admin_login
            two_factor:
                auth_form_path: 2fa_login
                check_path: 2fa_login_check

and Here's my access control:

access_control:
        - { path: ^/admin/login, roles: IS_AUTHENTICATED_ANONYMOUSLY }
        - { path: ^/admin/logout, role: [IS_AUTHENTICATED_ANONYMOUSLY, IS_AUTHENTICATED_2FA_IN_PROGRESS] }
        - { path: ^/admin/2fa, role: IS_AUTHENTICATED_2FA_IN_PROGRESS }
        - { path: ^/admin, role: ROLE_ADMIN }

@scheb
Copy link
Owner

scheb commented Nov 26, 2018

@wh1pp3rz Well, no idea. Looks good to me. You'd need to debug why the logout process isn't triggered, when calling that path.

@scheb
Copy link
Owner

scheb commented Nov 26, 2018

@AmbushIV Can't see anything in that application. It's all commented-out config, no idea what you're actually testing with.

And since you're saying it's an "API only backend": I'm not sure if this will play well together with the bundle. There are some mechanics, which rely on redirecting the user to a form, and to my understanding this redirect would happen within a backend API call. So instead of returning a HTML form, you'd probably need to return an API response (JSON?), which tells the frontend to show the 2fa form.

@AmbushIV
Copy link
Author

@scheb Thank you for your reply.

Indeed I need to return an API response after login to trigger the 2fa check and then to confirm the corect code with the backend. You think it's possible to do this with your bundle?

@wh1pp3rz
Copy link

@scheb the logout is called but for some reason, the logout is redirecting back to /2fa as opposed to what's set in the target of the firewall config.

@scheb
Copy link
Owner

scheb commented Nov 27, 2018

@wh1pp3rz is the route really /2fa? Not /admin/2fa?

@scheb
Copy link
Owner

scheb commented Nov 27, 2018

@AmbushIV Best solution for you would be to implement & configure custom authentication handlers, which return an API response instead of the default behavior. See https://github.com/scheb/two-factor-bundle/blob/master/Resources/doc/configuration.md

success_handler: acme.custom_success_handler # Use a custom success handler instead of the default one 
failure_handler: acme.custom_failure_handler # Use a custom failure handler instead of the default one

# Use a custom authentication required handler instead of the default one
# This can be used to modify the default behavior of the bundle, which is always redirecting to the
# two-factor authentication form, when two-factor authentication is required.
authentication_required_handler: acme.custom_auth_reqired_handler

Interfaces to be implemented would be:

  • Symfony\Component\Security\Http\Authentication\AuthenticationSuccessHandlerInterface
  • Symfony\Component\Security\Http\Authentication\AuthenticationFailureHandlerInterface
  • Scheb\TwoFactorBundle\Security\Http\Authentication\AuthenticationRequiredHandlerInterface

@wh1pp3rz
Copy link

@scheb the route /admin/2fa I only use /2fa for short in the description here. Basically once I'm on the /admin/2fa page I cannot navigate unless I enter a valid token. Even if I manually type I new url in the browser I'm redirected back to /admin/2fa

@scheb
Copy link
Owner

scheb commented Nov 27, 2018

@wh1pp3rz Well, in that case I'm out of ideas.

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

No branches or pull requests

3 participants