【问题标题】:is there a way to parse claims from an expired JWT token?有没有办法从过期的 JWT 令牌中解析声明?
【发布时间】:2021-08-17 01:41:25
【问题描述】:

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

有没有办法即使 JWT 已过期也能读取声明

下面用于解析java中的JWT:

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

【问题讨论】:

    标签: java jwt json-web-token


    【解决方案1】:

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

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

    ExpiredJwtException 构造如下:-

    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());
        }
    

    【讨论】:

      【解决方案2】:

      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

      【讨论】:

        【解决方案3】:

        这可能是旧的,但对于任何面临这个问题的人来说,java 的io.jsonwebtoken ExpiredJwtException 已经得到了声明,你可以通过调用 e.getClaims() 得到它。

        【讨论】:

        • 你这里所说的“Java”可能是JJWT库。
        • 你在重新陈述@Gautam 两年前写的内容......
        【解决方案4】:

        如果有人进来寻找 jose4j 库,那么下面的工作:

        invalidJwtException.getJwtContext().getJwtClaims()
        

        【讨论】:

          【解决方案5】:

          只需在调用 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;
          

          【讨论】:

            【解决方案6】:

            如果您使用io.jsonwebtoken,请尝试我的功能:

            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();
                    } 
                }
            

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 2021-04-21
              • 2020-01-15
              • 2020-06-01
              • 1970-01-01
              • 2019-01-14
              • 2019-04-04
              • 2017-10-21
              • 2019-10-13
              相关资源
              最近更新 更多