Reputation: 41
I have set claims in JWT token in the token provider. now I want to get claim value through authentication when API is hit.
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.
Upvotes: 3
Views: 89067
Reputation: 1
In newer versions of Jwts you will find the parser() as deprecated, in that case just use the parserBuilder().build() method in place of parser().
Hope this helps someone who is coping with this issue.
Upvotes: 0
Reputation: 311
// for retrieving any information from token we will need the signing key
private Claims getAllClaimsFromToken(String token) {
return Jwts.parser().verifyWith(<SigningKey>).build().parseSignedClaims(token).getPayload();
}
Upvotes: 4
Reputation: 89
If it is in quarkus, we can get it by injecting JSONWebToken:
/**
* Injection point for the ID Token issued by the OpenID Connect Provider
*/
@Inject
@IdToken
JsonWebToken idToken;
In Java, Keys for claim in keycloak provided by JSONWebToken can be accessed via getClaimNames() method. Following is an example:
Set<String> allClaims = this.idToken.getClaimNames();
for (String claimName: allClaims) {
System.out.println("Claim name: " + claimName);
}
Ref: https://quarkus.io/guides/security-openid-connect-web-authentication
Upvotes: 0
Reputation: 5291
List out all the claims using JWT
private void listClaimUsingJWT(String accessToken) {
try {
SignedJWT signedJWT = SignedJWT.parse(accessToken);
JWTClaimsSet claimsSet= signedJWT.getJWTClaimsSet();
Map<String,Object> myClain =claimsSet.getClaims();
String[] keySet = myClain.keySet().toArray(new String[0]);
Log.d("JWT_Claims", "loadAllOptionalClaim JWT keySetSize "+keySet.length);
for (String s : keySet) {
Log.d("JWT_Claims", "loadAllOptionalClaim JWT key ==> " + s + " ====> " + myClain.get(s));
}
} catch (Exception e) {
e.printStackTrace();
}
}
Upvotes: 0
Reputation: 186
Using Spring Security 5 you can use @AuthenticationPrincipal org.springframework.security.oauth2.jwt.Jwt token
as parameter in your controller method. And then call token.getClaims()
Upvotes: 1
Reputation: 7624
This is how I read Claim from Token
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
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>0.9.0</version>
</dependency>
Edit 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);
}
}
Upvotes: 5
Reputation: 2836
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)
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.
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
You should note that the ValidateToken method will return null
value if the validation fails.
Upvotes: 0