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)
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.