SmallRye refresh an expired JWT

618 views
Skip to first unread message

Rafael FNX

unread,
Aug 31, 2021, 12:51:29 AM8/31/21
to SmallRye

I'm trying to make an endpoint where it's possible for the user to refresh an expired JWT token, but even though the api/auth/refresh route is not secured (has no @RolesAllowed or @Authenticated annotation) the Smallrye JWT still prevents the invalid token get to the resource to be refreshed.

@POST
@Path("/refresh")
public Response refresh(@Context SecurityContext context) {
    var principal = context.getUserPrincipal();
    if (principal == null) return Response.status(Status.UNAUTHORIZED).build(); 
    
    return Response.ok(authService.refreshJWT(principal)).build();
}

My authService service checks if this token has been refreshed for more than 2 weeks, if not, it refreshes the token, otherwise it returns 401 and the user will have to login again. The problem is that by the time the token is sent, even before falling into this method I showed, Smallrye already returns 401 direct, because the token is expired, I think if the route is public, it doesn't need to be logged in to access it, this shouldn't happen.

How could I make the refresh route allowing expired tokens correctly?

Sergey Beryozkin

unread,
Aug 31, 2021, 6:40:49 AM8/31/21
to SmallRye
Hi Rafael

this is more of a Quarkus question (smallrye-jwt itself is at a lower level - it is not aware of the authentication requirements - ex that a given resource is public etc), please disable the proactive authentication, see


Note you can also ask about Quarkus at at

HTH
Sergey

--
You received this message because you are subscribed to the Google Groups "SmallRye" group.
To unsubscribe from this group and stop receiving emails from it, send an email to smallrye+u...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/smallrye/15395752-3cdf-4aa2-ab47-898100b5091bn%40googlegroups.com.

Rafael FNX

unread,
Sep 1, 2021, 2:44:01 PM9/1/21
to SmallRye
Hi again Sergey!
Jeez, only you to help me! haha. I asked the same question in both Quarkus chat at Zulip and StackOverflow, and so far nothing.
- https://quarkusio.zulipchat.com/#narrow/stream/187030-users/topic/SmallRye.20refresh.20an.20expired.20JWT

Your tip to remove proactive authentication was the solution! Thank you very much!

But now securityContext.getUserPrincipal() returns null, probably because token validation is no longer being performed, so I used the @HeaderParam("Authorization") annotation to get the encoded token in text.

To decode this token I then used io.smallrye.jwt.auth.principal.JWTParser, but it again throws the ParseException saying the token is no longer valid, which will always happen since i'm trying to refresh expired tokens. 
Then I tried using jose4j's JwtConsumerBuilder class and disable expiration validation, but this option does not exist, the only disabling methods are setSkipSignatureVerification(), setSkipAllValidators(), setSkipAllDefaultValidators(), setSkipVerificationKeyResolutionOnNone(), setSkipDefaultAudienceValidation(), none of them help me and if I disable all validation, then my system will accept spoofed tokens.

For now, I'm using JwtConsumerBuilder().setAllowedClockSkewInSeconds(Integer.MAX_VALUE), so it won't say that the token is expired as there is no longer an expiration time limit, but it looks like a hack.

Do you think I should ask the library staff to include the option not to validate the expiration date for the library?

Thank you so much for everything! You were the only one who helped me so far!

Sergey Beryozkin

unread,
Sep 2, 2021, 7:05:08 AM9/2/21
to SmallRye
Hi Rafael

On Wed, Sep 1, 2021 at 7:44 PM Rafael FNX <rfnicol...@gmail.com> wrote:
Hi again Sergey!
Jeez, only you to help me! haha. I asked the same question in both Quarkus chat at Zulip and StackOverflow, and so far nothing.
- https://quarkusio.zulipchat.com/#narrow/stream/187030-users/topic/SmallRye.20refresh.20an.20expired.20JWT

I missed that question on Zulip, you can see @Sergey Beryozkin next time.
 
Your tip to remove proactive authentication was the solution! Thank you very much!

But now securityContext.getUserPrincipal() returns null, probably because token validation is no longer being performed, so I used the @HeaderParam("Authorization") annotation to get the encoded token in text.

Can you clarify it please ? Token validation is always done if the method requires it - do you mean that in your public resource you have a null principal ? This is expected - by disabling the proactive authentication you have requested that the token is not verified when it is not needed - and since `JsonWebToken` is a principal you see a null in this case - as `Principal` must represent a verified user identity. 
 
To decode this token I then used io.smallrye.jwt.auth.principal.JWTParser, but it again throws the ParseException saying the token is no longer valid, which will always happen since i'm trying to refresh expired tokens. 
Then I tried using jose4j's JwtConsumerBuilder class and disable expiration validation, but this option does not exist, the only disabling methods are setSkipSignatureVerification(), setSkipAllValidators(), setSkipAllDefaultValidators(), setSkipVerificationKeyResolutionOnNone(), setSkipDefaultAudienceValidation(), none of them help me and if I disable all validation, then my system will accept spoofed tokens.

For now, I'm using JwtConsumerBuilder().setAllowedClockSkewInSeconds(Integer.MAX_VALUE), so it won't say that the token is expired as there is no longer an expiration time limit, but it looks like a hack.

It is not a hack if you'd like to use jose4j to parse the expired tokens - if you'd like you can simply Base64 URL decode the middle JWT token part and read it as JSON and avoid Jose4J completely in such cases where the token is not verified

Do you think I should ask the library staff to include the option not to validate the expiration date for the library?

No, in smallrye-jwt a token must have an expiration value - without it the token may be live for years and supporting such tokens is not safe
 
Thank you so much for everything! You were the only one who helped me so far!

Np, we are here to help. But each of us focuses on some specific areas, if you ask me now about the reactive messaging I'd ask Clement to help, etc.
I'm seeing quite often on Zulip and also Stack Overflow other users already answering the security questions - but not everyone may be immediately familiar with jose4j internals, etc :-)
 
Thanks, Sergey
Reply all
Reply to author
Forward
0 new messages