4
votes

I'm using this LexikJWTAuthenticationBundle with FosUserBundle.

I have this in security.yml :

firewalls:
    app:
        pattern: ^/api
        stateless: true
        anonymous: true
        lexik_jwt: ~

with the following access_control :

- { path: ^/api/user/action1, roles: IS_AUTHENTICATED_FULLY }
- { path: ^/api/user/action2, roles: IS_AUTHENTICATED_ANONYMOUSLY }

The behaviour I was expecting for /api/user/action2 is having access no matter what is inside the request header. However I'm getting a 401 in the case where the Authorization Bearer is set but not valid (it is ok with valid token or no Authorization Bearer at all).

My use case is I need to check in my controller if the user is logged in but if not, I still want to let that anonymous user access the route.

2

2 Answers

1
votes

You have to create a specific firewall for the route/pattern you want allow for anonymous users :

action2:
    pattern: ^/api/user/action2
    anonymous: true
    lexik_jwt: ~

Then, just move your less-protected access_control just before the fully-protected :

- { path: ^/api/user/action2, roles: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/api/user/action1, roles: IS_AUTHENTICATED_FULLY }

In this way, you are application doesn't care about an Authorization header, and all users can access the resource without JWT.

Update

Change the anonymous route's firewall to :

action2:
    pattern: ^/api/user/action2
    anonymous: true
    lexik_jwt: ~

And make the access_control accepting anonymous And fully authenticated users :

- { path: ^/api/user/action2, roles: [IS_AUTHENTICATED_ANONYMOUSLY, IS_AUTHENTICATED_FULLY]  }
- { path: ^/api/user/action1, roles: IS_AUTHENTICATED_FULLY }

Please use the same order and clear your cache correctly.

It's working well in my JWT/FOSUB application, if it doesn't work for you I'll give you a working ready-to-use example.

And the controller :

$currentToken = $this->get('security.token_storage')->getToken();

if (is_object($currentToken->getUser())) {
    // Do your logic with the current user
    return new JsonResponse(['user' => $currentToken->getUser()->getUsername()]);
} else {
    return new JsonResponse(['user' => 'Anonymous']);
}

Hope it works for you.

0
votes

I resolved your problem in this way:

    api_public:
        pattern: ^/api/v1/public
        anonymous: true
        lexik_jwt:
            authorization_header:
                enabled: false
                prefix:  Bearer
            query_parameter:
                enabled: false
                name:    bearer
    api:
        pattern:   ^/api
        stateless: true
        anonymous: true
        lexik_jwt:
            authorization_header:
                enabled: true
                prefix:  Bearer
            query_parameter:
                enabled: true
                name:    bearer