I have an API Backend as a central user repository use Symfony, Api bundle, LexikJWTAuthenticationBundle, and JWTRefreshTokenBundle, suppose we name it User Backend.
Every other backend system that I have will connect to the User Backend and authenticate using JWT token that provided by User Backend.
What I want to ask is, If I want to impersonate other user on the other backend, I need to get the JWT token for the impersonated token. How to do that?
On the user Backend, I have /api/authentication
endpoint which is the default from LexikJWTAuthenticationBundle.
I try to use the following configuration on security.yaml
:
security:
enable_authenticator_manager: true
# https://symfony.com/doc/current/security.html#registering-the-user-hashing-passwords
password_hashers:
Symfony\Component\Security\Core\User\PasswordAuthenticatedUserInterface: 'auto'
App\Entity\User\User:
algorithm: auto
# https://symfony.com/doc/current/security.html#loading-the-user-the-user-provider
providers:
users_in_memory: { memory: null }
# used to reload user from session & other features (e.g. switch_user)
app_user_provider:
entity:
class: App\Entity\User\User
property: username
role_hierarchy:
ROLE_SUPER_ADMIN:
- ROLE_ADMIN
- ROLE_ALLOWED_TO_SWITCH
firewalls:
api_token_refresh:
pattern: ^/api/token/refresh
stateless: true
refresh_jwt:
provider: app_user_provider
dev:
pattern: ^/(_(profiler|wdt)|css|images|js)/
security: false
login:
pattern: ^/api/authentication$
stateless: true
switch_user:
provider: app_user_provider
role: ROLE_ALLOWED_TO_SWITCH
json_login:
check_path: /api/authentication
username_path: username
password_path: password
provider: app_user_provider
success_handler: lexik_jwt_authentication.handler.authentication_success
failure_handler: lexik_jwt_authentication.handler.authentication_failure
api:
pattern: ^/api/
stateless: true
switch_user:
provider: app_user_provider
role: ROLE_ALLOWED_TO_SWITCH
provider: app_user_provider
jwt: ~
main:
lazy: true
provider: app_user_provider
custom_authenticator: App\Security\AdminAuthenticator
logout:
path: app_logout
# where to redirect after logout
# target: app_any_route
json_login:
check_path: app_json_login
username_path: username
password_path: password
# 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: ^/api/token/refresh, roles: PUBLIC_ACCESS }
- { path: ^/api/authentication, roles: PUBLIC_ACCESS }
- { path: ^/api, roles: PUBLIC_ACCESS }
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
But with the above configuration, I try to send a request like: /api/authentication?_switch_user=other_user
, I always get the real user token, not the one I want to impersonate.