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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/54339794/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 01:01:32  来源:igfitidea点击:

how to get claims value from JWT token authentication

javaspringspring-bootspring-securityjwt

提问by sameer nainawat

I have set claims in JWT token in the token provider. now I want to get claim value through authentication when API is hit.

我在令牌提供程序中的 JWT 令牌中设置了声明。现在我想在 API 被命中时通过身份验证获得声明值。

I have checked in Principal, details, credential, authorities but I am not getting claims in any of them.

我已经检查了校长、详细信息、证书、权限,但我没有收到任何索赔。

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

I want to get "userId" claim from the authentication or any other way to get claims value from token.

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

回答by Kunal Vohra

It should help.

它应该有帮助。

You should be able to retrieve a claims like this within your controller

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

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

}

If you wanted, you could write extension methods for the IPrincipal interface and retrieve claims using the code above, then retrieve them using (for example)

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

HttpContext.User.Identity.MethodName();


For completeness of the answer. To Decode the JWT token let's write a method to validate the token and extract the information.

为了答案的完整性。为了解码 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;
    }

Now we can validate and extract the Claims by using:

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

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

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

You should note that the ValidateToken method will return nullvalue if the validation fails.

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

回答by MyTwoCents

This is how I read Claim from Token

这就是我从 Token 中读取 Claim 的方式

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

I am using this for JWT

我将它用于 JWT

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

More detail here

更多细节在这里

Edit 1:

编辑1:

Adding Filter to get token from Request and Validate

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

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



}

回答by Vineeth Bhaskaran

It would be recommended to refer the blog given below. It explained how the JWT token works in spring boot

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

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

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