如何从JWT令牌认证获取声明值

时间:2019-01-24 05:17:34

标签: java spring spring-boot spring-security jwt

我在令牌提供者的JWT令牌中设置了声明。现在我想在点击API时通过身份验证来获取声明值。

我已经检查了校长,详细信息,证书,授权,但是我没有收到任何要求。

Claims claims = Jwts.claims().setSubject(authentication.getName());
    claims.put(AUTHORITIES_KEY, authorities);
    claims.put("userId", userRepo.findUserIdByUsername(authentication.getName()));

   return Jwts.builder()
            .setSubject(authentication.getName())
            .setClaims(claims)
            //.claim(AUTHORITIES_KEY, authorities)
            .signWith(SignatureAlgorithm.HS512, SIGNING_KEY)
            .setIssuedAt(new Date(System.currentTimeMillis()))
            .setExpiration(new Date(System.currentTimeMillis() + ACCESS_TOKEN_VALIDITY_SECONDS*1000))
            .compact();

我想从身份验证中获取“ userId”声明,或从令牌中获取声明值的任何其他方式。

4 个答案:

答案 0 :(得分:0)

应该有帮助。

您应该能够在控制器中检索这样的声明

var identity = HttpContext.User.Identity as ClaimsIdentity;
if (identity != null)
{
    IEnumerable<Claim> claims = identity.Claims; 
    // or
    identity.FindFirst("ClaimName").Value;

}

如果需要,您可以为IPrincipal接口编写扩展方法并使用上面的代码检索声明,然后使用(例如)检索声明

HttpContext.User.Identity.MethodName();

答案的完整性。为了解码JWT令牌,我们编写一个方法来验证令牌并提取信息。

public static ClaimsPrincipal ValidateToken(string jwtToken)
    {
        IdentityModelEventSource.ShowPII = true;

        SecurityToken validatedToken;
        TokenValidationParameters validationParameters = new TokenValidationParameters();

        validationParameters.ValidateLifetime = true;

        validationParameters.ValidAudience = _audience.ToLower();
        validationParameters.ValidIssuer = _issuer.ToLower();
        validationParameters.IssuerSigningKey = new Microsoft.IdentityModel.Tokens.SymmetricSecurityKey(Encoding.UTF8.GetBytes(_appSettings.Secret));

        ClaimsPrincipal principal = new JwtSecurityTokenHandler().ValidateToken(jwtToken, validationParameters, out validatedToken);


        return principal;
    }

现在我们可以使用以下方法来验证并提取声明:

ValidateToken(tokenString)?.FindFirst("ClaimName")?.Value

您应该注意,如果验证失败,ValidateToken方法将返回null值。

答案 1 :(得分:0)

这就是我从令牌中读取声明

的方式
private Claims getAllClaimsFromToken(String token) {
        Claims claims;
        try {
            claims = Jwts.parser()
                    .setSigningKey(SECRET)
                    .parseClaimsJws(token)
                    .getBody();
        } catch (Exception e) {
            LOGGER.error("Could not get all claims Token from passed token");
            claims = null;
        }
        return claims;
    }

我正在将其用于JWT

<dependency>
    <groupId>io.jsonwebtoken</groupId>
    <artifactId>jjwt</artifactId>
    <version>0.9.0</version>
</dependency>

More detail here

编辑1:

添加过滤器以从请求和验证中获取令牌

import java.io.IOException;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.web.filter.OncePerRequestFilter;

public class TokenAuthenticationFilter extends OncePerRequestFilter {

    protected final Log logger = LogFactory.getLog(getClass());

    private TokenHelper tokenHelper;

    private UserDetailsService userDetailsService;

    public TokenAuthenticationFilter(TokenHelper tokenHelper, UserDetailsService userDetailsService) {
        this.tokenHelper = tokenHelper;
        this.userDetailsService = userDetailsService;
    }


    @Override
    public void doFilterInternal(
            HttpServletRequest request,
            HttpServletResponse response,
            FilterChain chain
    ) throws IOException, ServletException {

        String username;
        String authToken = tokenHelper.getToken(request);

        logger.info("AuthToken: "+authToken);

        if (authToken != null) {
            // get username from token
            username = tokenHelper.getUsernameFromToken(authToken);
            logger.info("UserName: "+username);
            if (username != null) {
                // get user
                UserDetails userDetails = userDetailsService.loadUserByUsername(username);
                if (tokenHelper.validateToken(authToken, userDetails)) {
                    // create authentication
                    TokenBasedAuthentication authentication = new TokenBasedAuthentication(userDetails);
                    authentication.setToken(authToken);
                    SecurityContextHolder.getContext().setAuthentication(authentication);
                }
            }else{
                logger.error("Something is wrong with Token.");
            }
        }
        chain.doFilter(request, response);
    }



}

答案 2 :(得分:0)

建议参考以下博客。它解释了JWT令牌在Spring Boot中如何工作

https://auth0.com/blog/implementing-jwt-authentication-on-spring-boot/

答案 3 :(得分:0)

使用Spring Security 5,您可以在控制器方法中使用@AuthenticationPrincipal org.springframework.security.oauth2.jwt.Jwt token作为参数。然后致电token.getClaims()