symfonyapi-platform.comlexikjwtauthbundle

Multiples firewalls with same pattern


I currently have the following configuration, Endpoints /api work fine when sending token from external consumers.

But I now want to reuse this pattern ^/api, with ajax in my application that is using sessions. How can I configure the firewall to work for me either stateless or with sessions?

security:
    encoders:
        FOS\UserBundle\Model\UserInterface: bcrypt
        App\Entity\User\User:
            algorithm: bcrypt

    role_hierarchy:
        ROLE_ADMIN: [ROLE_USER, ROLE_ALLOWED_TO_SWITCH]
        ROLE_SUPER_ADMIN: ROLE_ADMIN

    providers:
        fos_userbundle:
            id: fos_user.user_provider.username_email
        app_user_provider:
            entity:
                class: App\Entity\User\User
                property: username

    firewalls:
        dev:
            pattern: ^/(_(profiler|wdt)|css|images|js)/
            security: false
        logout:
            pattern: ^/api/logout
            stateless: true
            anonymous: true
            logout:
                path:  app_logout
                success_handler: "app.webservice_logout_success_listener"
        api:
            pattern: ^/api
            stateless: true
            anonymous: true
            provider: app_user_provider
            json_login:
                check_path: /api/login_check
                username_path: username
                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
        admin:
            context: user
            switch_user: true
            pattern:  ^/
            anonymous: ~
            provider: fos_userbundle
            form_login:
                login_path: admin_login
                check_path: admin_login
                default_target_path: easyadmin
                failure_path: admin_login
            logout:
                path:   /logout
                target: /login


Solution

  • I found a solution, sorry for taking time to reply. The solution I don't know if it will be the best approach, but I would like to know opinions about other possible implementations.

    On the one hand, I enable Lexik, to obtain the token of a cookie.

    # config/packages/lexik_jwt_authentication.yaml
    lexik_jwt_authentication:
        # some_config:
        token_extractors:
            # check token in a cookie
            cookie:
                enabled: true
                name:    Bearer
    

    On the other hand, I override the function when a user is authenticated by session, setting the cookie and with the token generated programmatically with Lexik

    <?php
    
    namespace App\Security;
    
    use Lexik\Bundle\JWTAuthenticationBundle\Services\JWTTokenManagerInterface;
    use Symfony\Component\HttpFoundation\Cookie;
    use Symfony\Component\Security\Http\Authentication\DefaultAuthenticationSuccessHandler as BaseDefaultAuthenticationSuccessHandler;
    use Symfony\Component\HttpFoundation\Request;
    use Symfony\Component\HttpFoundation\Response;
    use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
    use Symfony\Component\Security\Http\HttpUtils;
    
    class DefaultAuthenticationSuccessHandler extends BaseDefaultAuthenticationSuccessHandler
    {
    
        private $JWTManager;
    
        public function __construct(
            JWTTokenManagerInterface $JWTManager,
            HttpUtils $httpUtils,
            array $options = []
        )
        {
            parent::__construct($httpUtils, $options);
            $this->JWTManager = $JWTManager;
        }
    
        public function onAuthenticationSuccess(Request $request, TokenInterface $token)
        {
            /** @var Response $response */
            $response = parent::onAuthenticationSuccess($request, $token);
            $response->headers->setCookie(Cookie::create('Bearer', $this->JWTManager->create($token->getUser())));
            return $response;
        }
    }