1

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.

khgasd652k
  • 281
  • 1
  • 9
  • your switch_user have to define the param: https://symfony.com/doc/current/security/impersonating_user.html#controlling-the-query-parameter switch_user: { role: ROLE_ADMIN, parameter: _switch_user } And you have to impliment some code like $token = $this->security->getToken(); if ($token instanceof SwitchUserToken) { $impersonatorUser = $token->getOriginalToken()->getUser(); } – episch Mar 20 '22 at 14:37

0 Answers0