有没有办法从过期的JWT令牌中解析声明?

时间:2016-03-04 08:40:21

标签: java jwt json-web-token

如果我们尝试解析已过期 JWT,则会导致过期异常。

即使JWT已过期,是否有办法阅读声明

下面用于解析java中的JWT:

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

5 个答案:

答案 0 :(得分:15)

有一种更好的方法可以做到这一点。 如果您看到JWT异常处理程序对象,例如ExpiredJwtException,期望对象本身包含以下内容: - 标题,声明和消息

因此可以通过此对象轻松提取声明,即e.getClaims().getId(),其中e是ExpiredJwtException对象。

ExpiredJwtException consturct如下: -

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

示例: -

    try{
        // executable code
   }catch(ExpiredJwtException e){
        System.out.println("token expired for id : " + e.getClaims().getId());
    }

答案 1 :(得分:11)

JWT对象是Base64URL编码的。这意味着您始终可以通过手动Base64URL解码来读取标头和有效负载。在这种情况下,您只需忽略exp属性。

例如,您可以这样做(我使用的是Java8内置Base64类,但您可以使用任何外部库,例如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

,输出为:

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

另请注意,exp属性设置为1300819380,与16 january 2016对应。

答案 2 :(得分:1)

这可能已经很老了,但是对于任何面临此问题的人,Java的io.jsonwebtoken  ExpiredJwtException已包含其中的声明,您可以致电e.getClaims()来获取它。

答案 3 :(得分:0)

如果有人来寻找jose4j库,则可以使用以下方法:

invalidJwtException.getJwtContext().getJwtClaims()

答案 4 :(得分:0)

在调用 ValidateToken 之前,只需将 TokenValidationParameters 的 ValidateLifetime 属性设置为 false。

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

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

然后你可以像这样阅读声明:

string name = principal.Claims.FirstOrDefault(e => e.Type.Equals(ClaimTypes.Name)).Value;
string email = principal.Claims.FirstOrDefault(e => e.Type.Equals(ClaimTypes.Email)).Value;