Lexikjwtauthenticationbundle: Checking user at token validating

Created on 7 Jul 2016  路  5Comments  路  Source: lexik/LexikJWTAuthenticationBundle

Hello,

after obtaining a token I want to check the user at every request with this token.

When I lock this user (or disable or expire) I expect that the token is rejected at the next request. But the token is available.

Is this a bug?

Most helpful comment

This is my working solution:

    public function onTokenDecoded(JWTDecodedEvent $event)
    {
        $payload = $event->getPayload();

        $account = $this->accountManager->getAccountByName($payload['username']);
        if (!$account
            || !$account->isEnabled()
            || !$account->isAccountNonExpired()
            || !$account->isAccountNonLocked()
            || !$account->isCredentialsNonExpired()
        ) {
            $event->markAsInvalid();
        }
    }

I use the other events for logging of failures too.

All 5 comments

Hello @tloeffler,

I think there is something that is important to mention: A JWT Token _cannot_ be invalidated, it has a lifetime and it auto-expires when this one is reached.
That is part of the specification and come with its pros and cons.

That does not mean that you can't do anything for that, but it can't be automatically done based on the field you given.

My guess is that if you remove some of his roles, it will not be possible for him to access a resource that require to be granted with a role that he doesn't have anymore, I will confirm it at the end of this day.

If you don't want to do it via changing the roles of your users (that I can totally understand!) and rather base the authorization on a specific field (locked, disabled, expire, fields that totally depend on your user provider that we don't manage), you should look at our authentication listeners, especially the on_jwt_decoded event.

What you can do is to create the listener as documented and, rather than checking request informations as shown, you can inject the repository of your User entity into your listener and, using the payload present in the JWTDecodedTokenEvent, fetch your user via UserRepository::findBy([$userIdentityField => $payload[$userIdentityField]), then if your user has its property "enabled" or "expire" to false, just mark the event as invalid (as shown in the doc).

Hope this helps. Do not hesitate to ask me for details.

Yes, this seems a possible solution (with the listener). I will check it, thank you :)

You're welcome. Please keep me informed when you tried it, either by closing this issue or giving your feedback. I think that it can be useful to describe more use cases where this event can be useful, especially for the one described by this issue.

This is my working solution:

    public function onTokenDecoded(JWTDecodedEvent $event)
    {
        $payload = $event->getPayload();

        $account = $this->accountManager->getAccountByName($payload['username']);
        if (!$account
            || !$account->isEnabled()
            || !$account->isAccountNonExpired()
            || !$account->isAccountNonLocked()
            || !$account->isCredentialsNonExpired()
        ) {
            $event->markAsInvalid();
        }
    }

I use the other events for logging of failures too.

馃憤 Thank's for sharing it @tloeffler , it will help for improve the documentation on this point.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

tsdevelopment picture tsdevelopment  路  4Comments

astronati picture astronati  路  5Comments

pbalan picture pbalan  路  5Comments

reducio picture reducio  路  4Comments

mflasquin picture mflasquin  路  5Comments