scheb / 2fa

Two-factor authentication for Symfony applications 🔐
MIT License
509 stars 75 forks source link

Always getting error "invalid_code" #244

Closed hackandcode-at closed 2 months ago

hackandcode-at commented 2 months ago

Bundle version: 7.5.0 Symfony version: 7.1 PHP version: 8.2

Description

I implemented the scheb/2fa-bundle for the Google Authenticator, I am able to add it to the app, but if I try to login, I only get the error "code_invalid".

To Reproduce

Additional Context

security.yaml

security:
    # https://symfony.com/doc/current/security.html#registering-the-user-hashing-passwords
    password_hashers:
        Symfony\Component\Security\Core\User\PasswordAuthenticatedUserInterface: 'auto'
    # https://symfony.com/doc/current/security.html#loading-the-user-the-user-provider
    providers:
        #users_in_memory: { memory: null }
        app_user_provider:
                    entity:
                        class: App\Entity\User
                        property: username
    firewalls:
        #dev:
        #    pattern: ^/(_(profiler|wdt)|css|images|js)/
        #    security: false

        main:
            lazy: true
            provider: app_user_provider
            pattern: ^/
            form_login:
                login_path: app_login
                check_path: app_login
                username_parameter: _username
                password_parameter: _password
                default_target_path: app_dashboard
                enable_csrf: true
                csrf_token_id: 'authenticate'
                csrf_parameter: '_csrf_token'
            logout:
                path: app_logout
            two_factor:
                auth_form_path: 2fa_login
                check_path: 2fa_login_check
                enable_csrf: true
                csrf_token_id: 'authenticate'
                csrf_parameter: '_csrf_token'
                default_target_path: app_dashboard
            remember_me:
                secret: '%kernel.secret%'
                lifetime: 604800
                path: /
                always_remember_me: true
            # activate different ways to authenticate
            # https://symfony.com/doc/current/security.html#the-firewall

            # 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: ^/2fa, role: IS_AUTHENTICATED_2FA_IN_PROGRESS }
        - { path: ^/admin, roles: ROLE_ADMIN }
        - { path: ^/dashboard, roles: ROLE_USER }

when@test:
    security:
        password_hashers:
            # By default, password hashers are resource intensive and take time. This is
            # important to generate secure password hashes. In tests however, secure hashes
            # are not important, waste resources and increase test times. The following
            # reduces the work factor to the lowest possible values.
            Symfony\Component\Security\Core\User\PasswordAuthenticatedUserInterface:
                algorithm: auto
                cost: 4 # Lowest possible value for bcrypt
                time_cost: 3 # Lowest possible value for argon
                memory_cost: 10 # Lowest possible value for argon

scheb_two_factor.yaml

scheb_two_factor:
    security_tokens:
        - Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken
        - Symfony\Component\Security\Http\Authenticator\Token\PostAuthenticationToken
    google:
        enabled: true
        server_name: "shortdot.local"
        issuer: "Shortdot Dashboard"
        digits: 6
        leeway: 15
        template: "security/2fa_form.html.twig"
    trusted_device:
        enabled: false

    ip_whitelist:
        - "127.0.0.1"
        - "::1"

In my Logs I get this messages

172.19.0.4 -  26/Aug/2024:08:41:10 +0200 "GET /index.php" 404
NOTICE: PHP message: [info] Matched route "2fa_login_check".
NOTICE: PHP message: [debug] Read existing security token from the session.
NOTICE: PHP message: [debug] User was reloaded from a user provider.
NOTICE: PHP message: [debug] Checking for authenticator support.
NOTICE: PHP message: [debug] Checking support on authenticator.
NOTICE: PHP message: [debug] Checking support on authenticator.
NOTICE: PHP message: [debug] Authenticator does not support the request.
NOTICE: PHP message: [debug] Checking support on authenticator.
NOTICE: PHP message: [debug] Authenticator does not support the request.
NOTICE: PHP message: [debug] Notified event "Symfony\Component\Security\Http\Event\CheckPassportEvent" to listener "Symfony\Component\Security\Http\EventListener\UserProviderListener::checkPassport".
NOTICE: PHP message: [debug] Notified event "Symfony\Component\Security\Http\Event\CheckPassportEvent" to listener "Symfony\Component\Security\Http\EventListener\UserProviderListener::checkPassport".
NOTICE: PHP message: [debug] Notified event "Symfony\Component\Security\Http\Event\CheckPassportEvent" to listener "Symfony\Component\Security\Http\EventListener\CsrfProtectionListener::checkPassport".
NOTICE: PHP message: [debug] Notified event "Symfony\Component\Security\Http\Event\CheckPassportEvent" to listener "Symfony\Component\Security\Http\EventListener\UserCheckerListener::preCheckCredentials".
NOTICE: PHP message: [debug] Notified event "Symfony\Component\Security\Http\Event\CheckPassportEvent" to listener "Symfony\Component\Security\Http\EventListener\CheckCredentialsListener::checkPassport".
NOTICE: PHP message: [debug] Notified event "Symfony\Component\Security\Http\Event\CheckPassportEvent" to listener "Scheb\TwoFactorBundle\Security\Http\EventListener\CheckTwoFactorCodeListener::checkPassport".
NOTICE: PHP message: [info] Authenticator failed.
NOTICE: PHP message: [info] Two-factor authentication request failed.
NOTICE: PHP message: [debug] The "Scheb\TwoFactorBundle\Security\Http\Authenticator\TwoFactorAuthenticator" authenticator set the failure response.
NOTICE: PHP message: [debug] Clearing remember-me cookie.
NOTICE: PHP message: [debug] Notified event "Symfony\Component\Security\Http\Event\LoginFailureEvent" to listener "Symfony\Component\Security\Http\EventListener\RememberMeListener::clearCookie".
NOTICE: PHP message: [debug] The "Scheb\TwoFactorBundle\Security\Http\Authenticator\TwoFactorAuthenticator" authenticator set the response. Any later authenticator will not be called
scheb commented 2 months ago

Please check if your server time and time on the 2fa device is configured correctly and in sync. The Google Authenticator code is time based and when time on the two devices is to much apart, it is impossible to enter a correct code. You have a leeway of 15 secs defined, which might not be enough.

hackandcode-at commented 2 months ago

I now used the Timezone Europe/Vienna (which is my timezone) for the Server and my client but it still does not work, also I am not able to define a leeway of like 30 seconds

scheb commented 2 months ago

Same time zone is not really necessary. Important thing is that both devices must have their time mostly in any in UTC time respectively. A time difference bigger than the configured leeway will lead to problems. So a server should be synced with a time providing service (NTP server) and the phone is ideally synced with phone network time. That way the time drift is kept to a minimum. Also Google Authenticator app has an option to sync time manually.

The other thing to check would be if both server-side and 2fa app have the same secret code configured. Otherwise it will be impossible to get the correct code.

hackandcode-at commented 2 months ago

Okay I will try this, I run the Application in Docker could this make any problem?

hackandcode-at commented 2 months ago

Fixed it! it was the Timezone Thank you so much!