2fa: code from auth app is not accepted

Bundle version: 5.8.0 Symfony version: 5.2.6 PHP version:8.0.3 Using authenticators (enable_authenticator_manager: true): NO “spomky-labs/otphp” “version”: “v10.0.1”,

Description

Hello I am stuck with the google authentication basically code from auth app is not accepted I followed Troubleshooting and still not working

I have a controller

use Scheb\TwoFactorBundle\Security\TwoFactor\Provider\Google\GoogleAuthenticatorInterface;
use Scheb\TwoFactorBundle\Security\TwoFactor\QrCode\QrCodeGenerator;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;

class QrCodeController extends AbstractController
{


    /**
     * @Route("/gen-secret", name="gen-secret")
     * @param GoogleAuthenticatorInterface $googleAuthenticator
     * @return JsonResponse
     */
    public function generateSecret(GoogleAuthenticatorInterface $googleAuthenticator): JsonResponse
    {

        $secret = $googleAuthenticator->generateSecret();

        return new JsonResponse($secret, 200);
    }


    /**
     * @Route("/qr-code", name="qr_code")
     */
    public function displayGoogleAuthenticatorQrCode(QrCodeGenerator $qrCodeGenerator): Response
    {
        // $qrCode is provided by the endroid/qr-code library. See the docs how to customize the look of the QR code:
        // https://github.com/endroid/qr-code
        $qrCode = $qrCodeGenerator->getGoogleAuthenticatorQrCode(user: $this->getUser());

        return new Response($qrCode->writeString(), 200, ['Content-Type' => 'image/png']);
    }

    /**
     * @Route("/check", name="gen-secret")
     * @param GoogleAuthenticatorInterface $googleAuthenticator
     * @return JsonResponse
     */
    public function getCode(GoogleAuthenticatorInterface $googleAuthenticator): JsonResponse
    {

        $secret = $googleAuthenticator->checkCode($this->getUser(),826316);

        return new JsonResponse($secret, 200);
    }
}

first I generate the secret by “/gen-secret” and paste it to

 /**
     * @ORM\Column(name="googleAuthenticatorSecret", type="string", nullable=true)
     */
    private $googleAuthenticatorSecret; 

save it and then generating the qr code comparing the secret in qr code I got in mobile the same as in database

then I am using the checkCode of googleAuthenticator and login as user that have the same secret code as in mobile phone and and enter as the second argument to $googleAuthenticator->checkCode($this->getUser(),826316); code that I got from auth app and I got bad response by “/check”

{
"error": "access_denied",
"2fa_complete": false
}

I already checked time by twig {{ “now”|date(“Y-m-d H:i:s”) }} and it’s the same as UTC

# api/config/packages/security.yaml
security:
    encoders:
        App\Entity\User:
            algorithm: argon2i

    # https://symfony.com/doc/current/security.html#where-do-users-come-from-user-providers
    providers:
        # used to reload user from session & other features (e.g. switch_user)
        app_user_provider:
            entity:
                class: App\Entity\User
                property: email

    firewalls:
        dev:
            pattern: ^/_(profiler|wdt)
            security: false
        main:
            stateless: true
            anonymous: true
            provider: app_user_provider
            two_factor:
                prepare_on_login: true
                prepare_on_access_denied: true
                authentication_required_handler: api_2fa_required_handler
                success_handler: lexik_jwt_authentication.handler.authentication_success
                failure_handler: lexik_jwt_authentication.handler.authentication_failure
                check_path: 2fa_login_check  # The route name you have used in the routes.yaml
            json_login:
                check_path: authentication_token
                username_path: email
                password_path: password
                success_handler: lexik_jwt_authentication.handler.authentication_success
                failure_handler: lexik_jwt_authentication.handler.authentication_failure
            guard:
                authenticators:
                    - lexik_jwt_authentication.jwt_token_authenticator
            logout:
                path: auth_logout


        refresh:
            pattern: ^/token/refresh
            stateless: true
            anonymous: true
    access_control:
        # 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 }
        - { path: ^/qr-code, role: IS_AUTHENTICATED_ANONYMOUSLY }
        - { path: ^/gen-secret, role: IS_AUTHENTICATED_ANONYMOUSLY }
        - { path: ^/2fa_check, role: IS_AUTHENTICATED_2FA_IN_PROGRESS }
        # This ensures that the form can only be accessed when two-factor authentication is in progress.
        - { path: ^/2fa, role: IS_AUTHENTICATED_2FA_IN_PROGRESS }
        - { path: ^/docs, roles: IS_AUTHENTICATED_ANONYMOUSLY } # Allows accessing the Swagger UI
        - { path: ^/authentication_token, roles: IS_AUTHENTICATED_ANONYMOUSLY }
        - { path: ^/token/refresh, roles: IS_AUTHENTICATED_ANONYMOUSLY }
#        - { path: ^/, roles: IS_AUTHENTICATED_FULLY }

Additional Context


scheb_two_factor:
    security_tokens:
        - Lexik\Bundle\JWTAuthenticationBundle\Security\Authentication\Token\JWTUserToken

    google:
        enabled: true
        server_name: Lazy     # Server 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
        template: security/2fa_form.html.twig

api/templates/security/2fa_form.html.twig

{% block body %}
    {% include "@SchebTwoFactor/Authentication/form.html.twig" %}
    {{ "now"|date("Y-m-d H:i:s") }}
{% endblock %}

routes

2fa_login:
    path: /2fa
    defaults:
        _controller: "scheb_two_factor.form_controller:form"

2fa_login_check:
    path: /2fa_check

services.yaml

    api_success_handler:
        class: App\Security\AuthenticationSuccessHandler
    api_2fa_required_handler:
        class: App\Security\TwoFactorAuthenticationRequiredHandler
    api_2fa_success_handler:
        class: App\Security\TwoFactorAuthenticationSuccessHandler
    api_2fa_failure_handler:
        class: App\Security\TwoFactorAuthenticationFailureHandler

I am working in docker-compose from https://github.com/api-platform/api-platform

thanks

About this issue

  • Original URL
  • State: closed
  • Created 3 years ago
  • Comments: 18 (7 by maintainers)

Most upvoted comments

Then I don’t know what the issue is. I’d recommend you start where the AuthenticationException is thrown (what you have shown in the screenshot above) and investgate from there why the application thinks the provider hasn’t been prepared. The flag seems to be present in the session, so I have no explanation why this is happening.