is there a way to parse claims from an expired JWT token?
Asked Answered
A

6

26

If we try to parse an expired JWT, results in expired exception.

Is there a way to read claims even the JWT was expired.

Below is used to parse JWT in java:

Jwts.parser().setSigningKey(secret.getBytes()).parseClaimsJws(token).getBody();

Abagael answered 4/3, 2016 at 8:40 Comment(0)
M
23

JWT objects are Base64URL encoded. This means that you can always read headers and payload by manually Base64URL-decoding it. In this case you will simply ignore exp attribute.

For instance you can do like this (I'm using Java8 built-in Base64 class, but you can use any external library, such as Apache Commons Codec):

Base64.Decoder decoder = Base64.getUrlDecoder();
String src = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCIsImV4cCI6IjEzMDA4MTkzODAifQ.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.2GpoV9q_uguSg0Ku6peI5aZ2qBxO5qOA42zaS25gq_c";
String[] parts = src.split("\\."); // Splitting header, payload and signature
System.out.println("Headers: "+new String(decoder.decode(parts[0]))); // Header
System.out.println("Payload: "+new String(decoder.decode(parts[1]))); // Payload

and the output is:

Headers: {"alg":"HS256","typ":"JWT","exp":"1300819380"}
Payload: {"sub":"1234567890","name":"John Doe","admin":true}

Please note also that the exp attribute is set to 1300819380, which corresponds to 16 january 2016.

Mcclellan answered 4/3, 2016 at 8:43 Comment(0)
J
54

There is a better approach to do this. if you see JWT Exception handler object e.g. ExpiredJwtException, expection object itself contains the following:- header, claims and message

so claims can easily extracted through this object i.e. e.getClaims().getId() where e is ExpiredJwtException object.

ExpiredJwtException consturct is as follow:-

public ExpiredJwtException(Header header, Claims claims, String message) {
        super(header, claims, message);
}

Example:-

    try{
        // executable code
   }catch(ExpiredJwtException e){
        System.out.println("token expired for id : " + e.getClaims().getId());
    }
Jamajamaal answered 24/4, 2017 at 6:7 Comment(0)
M
23

JWT objects are Base64URL encoded. This means that you can always read headers and payload by manually Base64URL-decoding it. In this case you will simply ignore exp attribute.

For instance you can do like this (I'm using Java8 built-in Base64 class, but you can use any external library, such as Apache Commons Codec):

Base64.Decoder decoder = Base64.getUrlDecoder();
String src = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCIsImV4cCI6IjEzMDA4MTkzODAifQ.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.2GpoV9q_uguSg0Ku6peI5aZ2qBxO5qOA42zaS25gq_c";
String[] parts = src.split("\\."); // Splitting header, payload and signature
System.out.println("Headers: "+new String(decoder.decode(parts[0]))); // Header
System.out.println("Payload: "+new String(decoder.decode(parts[1]))); // Payload

and the output is:

Headers: {"alg":"HS256","typ":"JWT","exp":"1300819380"}
Payload: {"sub":"1234567890","name":"John Doe","admin":true}

Please note also that the exp attribute is set to 1300819380, which corresponds to 16 january 2016.

Mcclellan answered 4/3, 2016 at 8:43 Comment(0)
M
7

this might be old but for anyone whose facing this issue, the java's io.jsonwebtoken ExpiredJwtException already got the claims in it, you can get it by calling e.getClaims().

Merry answered 4/11, 2019 at 15:12 Comment(2)
The "the Java's" you speak of here is probably the JJWT library.Gilburt
You're re-stating what @Gautam wrote two years prior...Feder
R
4

If you use io.jsonwebtoken you try my function:

public Claims getClaimsFromToken(String token) {
        try {
            // Get Claims from valid token
            return Jwts.parser()
                    .setSigningKey(SECRET)
                    .parseClaimsJws(token)
                    .getBody();
            
        } catch (ExpiredJwtException e) {
            // Get Claims from expired token
            return e.getClaims();
        } 
    }
Rubrician answered 16/8, 2021 at 17:41 Comment(0)
R
0

If Someone comes in looking for jose4j library then below works:

invalidJwtException.getJwtContext().getJwtClaims()
Romilda answered 11/11, 2020 at 12:28 Comment(0)
M
0

Just set the ValidateLifetime property of the TokenValidationParameters to false before calling ValidateToken.

TokenValidationParameters tokenValidationParameters = new TokenValidationParameters();
tokenValidationParameters.ValidateLifetime = false;

JwtSecurityTokenHandler jwtSecurityTokenHandler = new JwtSecurityTokenHandler();
ClaimsPrincipal principal = jwtSecurityTokenHandler.ValidateToken(token, tokenValidationParameters, out SecurityToken validatedToken);

Then you can read the claims like this:

string name = principal.Claims.FirstOrDefault(e => e.Type.Equals(ClaimTypes.Name)).Value;
string email = principal.Claims.FirstOrDefault(e => e.Type.Equals(ClaimTypes.Email)).Value;
Margheritamargi answered 21/1, 2021 at 19:18 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.