scheb/two-factor-bundle

2fa form is not being shown

miguelmsoler opened this issue · 16 comments

Bundle version: 4.18.4
Symfony version: 3.4.49
PHP version: 3.4.0

Description

After login in with username and password I expect to see the 2fa default form. What I get is a user logged in and the url bar showing "my_ domain/login". The page I'm seeing has the main layout so I expeted to get "my_ domain/" in the url bar. I can see the user menu and I can logout.

I checked the troubleshooting guide and it got me here after verifying that I have a TwoFactorToken after the login but answering "no" to the second question.

Additional Context

security:
    # https://symfony.com/doc/current/security.html#where-do-users-come-from-user-providers
    providers:
        users_in_memory: { memory: null }
    firewalls:
        dev:
            pattern: ^/(_(profiler|wdt)|css|images|js)/
            security: false
        main:
            pattern: ^/
            provider: users_in_memory
            two_factor:
                auth_form_path: 2fa_login   
                check_path: 2fa_login_check 

            # activate different ways to authenticate
            # https://symfony.com/doc/current/security.html#firewalls-authentication

            # https://symfony.com/doc/current/security/impersonating_user.html
            # switch_user: true

    # Easy way to control access for large sections of your site
    # Note: Only the *first* access control that matches will be used
    access_control:
        # - { path: ^/admin, roles: ROLE_ADMIN }
        # - { path: ^/profile, roles: ROLE_USER }

        # This makes the logout route accessible during two-factor authentication. Allows the user to
        # cancel two-factor authentication, if they need to.
        - { path: ^/logout, role: IS_AUTHENTICATED_ANONYMOUSLY }
        # This ensures that the form can only be accessed when two-factor authentication is in progress.
        - { path: ^/2fa, role: IS_AUTHENTICATED_2FA_IN_PROGRESS }

I dumped the $token and $user objects after login. ROLE_ADMIN is lost after login.

TwoFactorToken {#485 ▼
  -authenticatedToken: UsernamePasswordToken {#520 ▼
    -credentials: "*******"
    -providerKey: "main"
    -user: Users {#523 ▼
      #id: 2
      #name: null
      #lastname: null
      #channelbrandIsolation: false
      #userschannelbrand: PersistentCollection {#550 ▶}
      -googleAuthenticatorSecret: "FBMNU3YOZMUS3VTH5DULOMKAATRAC7M5O4OJ2P5BR6OW4QYP4HMA"
      #username: "*******"
      #usernameCanonical: "********"
      #email: "*************@gmail.com"
      #emailCanonical: "************@gmail.com"
      #enabled: true
      #salt: null
      #password: *******************************************************************"
      #plainPassword: null
      #lastLogin: DateTime @1623091323 {#521 ▶}
      #confirmationToken: null
      #passwordRequestedAt: null
      #groups: ArrayCollection {#517 ▶}
      #roles: array:1 [▼
        0 => "ROLE_ADMIN"
      ]
    }
    -roles: array:2 [▶]
    -authenticated: true
    -attributes: []
  }
  -credentials: null
  -providerKey: "main"
  -attributes: []
  -twoFactorProviders: array:1 [▶]
}

Users {#523 ▼
  #id: 2
  #name: null
  #lastname: null
  #channelbrandIsolation: false
  #userschannelbrand: PersistentCollection {#550 ▶}
  -googleAuthenticatorSecret: "FBMNU3YOZMUS3VTH5DULOMKAATRAC7M5O4OJ2P5BR6OW4QYP4HMA"
  #username: "miguel"
  #usernameCanonical: "******"
  #email: "********@gmail.com"
  #emailCanonical: "*********@gmail.com"
  #enabled: true
  #salt: null
  #password: "*****************************************************"
  #plainPassword: null
  #lastLogin: DateTime @1623091323 {#521 ▶}
  #confirmationToken: null
  #passwordRequestedAt: null
  #groups: ArrayCollection {#517 ▶}
  #roles: array:1 [▼
    0 => "ROLE_ADMIN"
  ]
}

My routing.yml has:

2fa_login:
    path: /2fa
    defaults:
        # "scheb_two_factor.form_controller" references the controller service provided by the bundle.
        # You don't HAVE to use it, but - except you have very special requirements - it is recommended.
        _controller: "scheb_two_factor.form_controller:form"

In my config.yml:

scheb_two_factor:
    google:
        enabled: true
        server_name: ddd               # Server name used in QR code
        issuer: ddd              # Issuer name used in QR code
        digits: 6                      # Number of digits in authentication code
        window: 1                      # How many codes before/after the current one would be accepted as valid
    security_tokens:
        - Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken
        - Acme\AuthenticationBundle\Token\CustomAuthenticationToken
scheb commented

What happens if you manually go to /2fa after login?

It loads the same page again, with "my_ domain/login" in the url bar and the user logged in.

scheb commented

When you're saying "user logged in" does that mean you see a TwoFactorToken in the session or a different token?

I'm getting a TwoFactorToken in an onLogin event. So I think that's the token in the session, isn't it?

scheb commented

Not neccessarily, what token class do you see in the debug toolbar when that wrong page is shown?

I don't know why I'm not seeing the toolbar...

This is my configuration:

web_profiler:
    toolbar: true
    intercept_redirects: true
    excluded_ajax_paths: ''

I can see the redirections only:
This request redirects to http://localhost/app_dev.php/.
This request redirects to http://localhost/app_dev.php/2fa.
This request redirects to http://localhost/app_dev.php/login.

scheb commented

Well, you should get that debug toolbar working, otherwise we can just do blind guessing.

If you could figure out where that redirect from /2fa to /login is coming from, what is causing that redirect, that would help.

The toolbar disappears when I activate Google Authenticator. As soon as I put "enable: false" in google configuration, the toolbar appears again.

With this configuration, the toolbar works but I have no 2fa:

scheb_two_factor:
    security_tokens:
        - Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken
        - Acme\AuthenticationBundle\Token\CustomAuthenticationToken
    google:
        enabled: false
        server_name: ddd       # Server name used in QR code
        issuer:ddd            # Issuer name used in QR code
        digits: 6                      # Number of digits in authentication code
        window: 1                      # How many codes before/after the current one would be accepted as valid
scheb commented

Well, that is very odd. The bundle shouldn't break the debug toolbar. Did you check in the browser's network tab if you see any error 500s or something that would prevent the toolbar from loading? If so, check what the error is which is causing the 500. That wouldn't solve the problem that you're having with 2fa, but it brings us closer to a solution ;)

No error at all. This is really weird.

scheb commented

Well, that's unfortunate. Then, I'd recommend you should figure out where that redirect from /2fa to /login is coming from, and effectively what is causing that redirect.

I dumped the token In DefaultAuthenticationRequiredHandler::onAuthenticationRequired just before redirecting to auth_form_path and I got an UsernamePasswordToken. Shouldn't it be a TwoFactorToken?

scheb commented

Jea, that shouldn't happen. Should be a TwoFactorToken. You should check where/how that token is being overwritten.

Yeah, I think it's something related to the FOSUserBundle.

The problem was solved. Sorry, I sent you a wrong security.yml you would have seen the problem instantly I suppose.... I had - { path: ^/, role: ROLE_USER } in access_control before the 2fa rule so the latter was never reached.

My appologizes... this issue can be closed.

scheb commented

Yea, that's unfortunate, because that would have been obvious. Well, glad you fixed it! :)