Reputation: 11
I'm currently using the default JWT authentication in my API platform project. But I want to try adding 2 factor authentication (with google authenticator) to my projects.
I followed the following instructions:
If I login with an existing and valid email + pwd, I nicely get the response:
{"login": "success", "two_factor_complete": false}
However, no I don't know to continue: which endpoint should I use post my 2fa code?
I copy and pasted the 4 handlers from here (and didn't change a thing)
My config/routes/scheb_2fa.yaml
:
2fa_login:
path: /2fa
defaults:
_controller: "scheb_two_factor.form_controller::form"
2fa_login_check:
path: /2fa_check
My config/packages/scheb_2fa.yaml
:
scheb_two_factor:
security_tokens:
- Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken
- Symfony\Component\Security\Http\Authenticator\Token\PostAuthenticationToken
google:
enabled: true # If Google Authenticator should be enabled, default false
server_name: Server Name # Server name used in QR code
issuer: Issuer Name # Issuer name used in QR code
digits: 6 # Number of digits in authentication code
window: 1 # Depends on the version of Spomky-Labs/otphp used:
# Until v10: How many codes before/after the current one would be accepted
# From v11: Acceptable time drift in seconds
# template: security/2fa_form.html.twig # Template used to render the authentication form
My config/packages/security.yaml
:
security:
# https://symfony.com/doc/current/security.html#registering-the-user-hashing-passwords
password_hashers:
App\Entity\User: 'auto'
enable_authenticator_manager: true
# Symfony\Component\Security\Core\User\PasswordAuthenticatedUserInterface: 'auto'
# https://symfony.com/doc/current/security.html#loading-the-user-the-user-provider
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)|css|images|js)/
security: false
main:
stateless: false
lazy: true
provider: app_user_provider
json_login:
check_path: /authentication_token
username_path: email
password_path: password
success_handler: App\Security\AuthenticationSuccessHandler
#success_handler: lexik_jwt_authentication.handler.authentication_success
#failure_handler: lexik_jwt_authentication.handler.authentication_failure
jwt: ~
two_factor:
prepare_on_login: true
prepare_on_access_denied: true
authentication_required_handler: App\Security\TwoFactorAuthenticationRequiredHandler
success_handler: App\Security\TwoFactorAuthenticationSuccessHandler
failure_handler: App\Security\TwoFactorAuthenticationFailureHandler
auth_code_parameter_name: authCode
logout:
path: app_logout
# 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:
# 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: PUBLIC_ACCESS }
# 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: ^/api/docs, roles: PUBLIC_ACCESS } # Allows accessing the Swagger UI
- { route: api_entrypoint, roles: PUBLIC_ACCESS }
- { route: api_doc, roles: PUBLIC_ACCESS }
- { route: api_jsonld_context, roles: PUBLIC_ACCESS }
- { path: ^/authentication_token, roles: PUBLIC_ACCESS }
- { path: ^/request_password, roles: PUBLIC_ACCESS }
- { path: ^/set_password, roles: PUBLIC_ACCESS }
- { path: ^/api, roles: IS_AUTHENTICATED_FULLY }
- { path: ^/, roles: PUBLIC_ACCESS }
And I added the $googleAuthenticatorSecret
property to my User Entity, incl. the following functions:
public function isGoogleAuthenticatorEnabled(): bool
{
return null !== $this->googleAuthenticatorSecret;
}
public function getGoogleAuthenticatorUsername(): string
{
return $this->email;
}
public function getGoogleAuthenticatorSecret(): ?string
{
return $this->googleAuthenticatorSecret;
}
public function setGoogleAuthenticatorSecret(?string $googleAuthenticatorSecret): void
{
$this->googleAuthenticatorSecret = $googleAuthenticatorSecret;
}
All my existing users have a secret. And I added a secret to my Google Authenticator app. So that should work just fine.
But I have no clue how to set up/configure the endpoint to post the 2fa code to!
Thanks in advance!
Upvotes: 1
Views: 754