下面列出了怎么用io.jsonwebtoken.Claims的API类实例代码及写法,或者点击链接到github查看源代码。
@Test
public void shouldRetrieveTheEmailWhenItIsNotInJwtToken() throws Exception {
Map<String, Object> claimParams = new HashMap<>();
claimParams.put("preferred_username", "username");
Claims claims = new DefaultClaims(claimParams).setSubject("id");
DefaultJws<Claims> jws = new DefaultJws<>(new DefaultJwsHeader(), claims, "");
UserImpl user = new UserImpl("id", "[email protected]", "username");
keycloakSettingsMap.put(KeycloakConstants.USERNAME_CLAIM_SETTING, "preferred_username");
// given
when(tokenExtractor.getToken(any(HttpServletRequest.class))).thenReturn("token");
when(jwtParser.parseClaimsJws(anyString())).thenReturn(jws);
when(userManager.getById(anyString())).thenThrow(NotFoundException.class);
when(userManager.getOrCreateUser(anyString(), anyString(), anyString())).thenReturn(user);
keycloakAttributes.put("email", "[email protected]");
try {
// when
filter.doFilter(request, response, chain);
} catch (Exception e) {
e.printStackTrace();
throw e;
}
verify(userManager).getOrCreateUser("id", "[email protected]", "username");
}
public Map<String, Object> validateToken(String token) {
/* 成功则返回user 失败抛出未授权异常,但是如果要刷新token,我想也在这里完成,因为如果后面判断token是否过期
就还需要再解析一次token,解token是比较消耗性能的,因此这里需要一个东西存token
超时时间可以随着刷新自增长 最大为7天*/
Claims claims = getAllClaimsFromToken(token);
long difference = claims.getExpiration().getTime() - System.currentTimeMillis();
if (difference < 0) {
//无效 抛token过期异常
throw new AuthExpirationException(HttpStatus.UNAUTHORIZED, "登录身份信息过期");
}
if (difference < authProperties.getRefreshInterval()) {
//小于一定区间,刷新
token = refreshToken(claims);
claims.put("newToken", token);
}
return claims;
}
public static Authentication getAuthentication(HttpServletRequest request) {
// 从Header中拿到token
String token = request.getHeader(HEADER_STRING);
if (token == null) {
token = getTokenFromCookis(request);
}
if (token != null && !token.isEmpty()) {
// 解析 Token
Claims claims = Jwts.parser().setSigningKey(SECRET)
.parseClaimsJws(token).getBody();
// 获取用户名
String user = claims.get("UserId").toString();
// 获取权限(角色)
List<GrantedAuthority> authorities = AuthorityUtils.commaSeparatedStringToAuthorityList((String) claims.get("authorities"));
// 返回验证令牌
return user != null ? new UsernamePasswordAuthenticationToken(user, null, authorities) : null;
}
return null;
}
/**
*
* @param jwt json web token
* @return 解签实体
* @throws ExpiredJwtException token过期
* @throws UnsupportedJwtException 不支持的TOKEN
* @throws MalformedJwtException 参数格式形变等异常
* @throws SignatureException 签名异常
* @throws IllegalArgumentException 非法参数
*/
public static Claims parseJwt(String jwt) throws ExpiredJwtException, UnsupportedJwtException, MalformedJwtException, SignatureException, IllegalArgumentException {
return Jwts.parser()
.setSigningKey(DatatypeConverter.parseBase64Binary(secretKey))
.parseClaimsJws(jwt)
.getBody();
// 令牌ID -- claims.getId()
// 客户标识 -- claims.getSubject()
// 客户标识
// 签发者 -- claims.getIssuer()
// 签发时间 -- claims.getIssuedAt()
// 接收方 -- claims.getAudience()
// 访问主张-角色 -- claims.get("roles", String.class)
// 访问主张-权限 -- claims.get("perms", String.class)
}
@Override
protected void doFilterInternal(HttpServletRequest req, HttpServletResponse rsp, FilterChain filterChain)
throws ServletException, IOException {
String token = req.getHeader(config.getHeader());
if (token != null && token.startsWith(config.getPrefix() + " ")) {
token = token.replace(config.getPrefix() + " ", "");
try {
Claims claims = Jwts.parser().setSigningKey(config.getSecret().getBytes()).parseClaimsJws(token)
.getBody();
String username = claims.getSubject();
@SuppressWarnings("unchecked")
List<String> authorities = claims.get("authorities", List.class);
if (username != null) {
UsernamePasswordAuthenticationToken auth = new UsernamePasswordAuthenticationToken(username, null,
authorities.stream().map(SimpleGrantedAuthority::new).collect(Collectors.toList()));
SecurityContextHolder.getContext().setAuthentication(auth);
}
} catch (Exception ignore) {
SecurityContextHolder.clearContext();
}
}
filterChain.doFilter(req, rsp);
}
@Override
public Claims parse(final String token) {
return Jwts.parserBuilder().setSigningKeyResolver(new SigningKeyResolverAdapter() {
@Override
public Key resolveSigningKey(final JwsHeader header, final Claims claims) {
final String keyid = header.getKeyId();
if (keyid == null) {
throw new JwtException("Missing Key ID (kid) header field");
}
if (keys.containsKey(keyid)) {
return keys.get(keyid);
}
throw new SecurityException("Could not locate key: " + keyid);
}
}).build().parseClaimsJws(token).getBody();
}
public Authentication getAuthentication(String token) {
Claims claims = Jwts.parser()
.setSigningKey(secretKey)
.parseClaimsJws(token)
.getBody();
Collection<? extends GrantedAuthority> authorities =
Arrays.asList(claims.get(AUTHORITIES_KEY).toString().split(",")).stream()
.map(SimpleGrantedAuthority::new)
.collect(Collectors.toList());
User principal = new User(claims.getSubject(), "",
authorities);
return new UsernamePasswordAuthenticationToken(principal, "", authorities);
}
@Test
public void testSerializeKeyPair() throws Exception {
KeyPair keyPair = Keys.keyPairFor(SignatureAlgorithm.RS256);
String privateKey = AuthTokenUtils.encodeKeyBase64(keyPair.getPrivate());
String publicKey = AuthTokenUtils.encodeKeyBase64(keyPair.getPublic());
String token = AuthTokenUtils.createToken(AuthTokenUtils.decodePrivateKey(Decoders.BASE64.decode(privateKey), SignatureAlgorithm.RS256),
SUBJECT,
Optional.empty());
@SuppressWarnings("unchecked")
Jwt<?, Claims> jwt = Jwts.parser()
.setSigningKey(AuthTokenUtils.decodePublicKey(Decoders.BASE64.decode(publicKey), SignatureAlgorithm.RS256))
.parse(token);
assertNotNull(jwt);
assertNotNull(jwt.getBody());
assertEquals(jwt.getBody().getSubject(), SUBJECT);
}
/**
* Parses the JWT token and return a {@link QueryResponse} object containing the domain, user id, type (Zowe / z/OSMF),
* date of creation and date of expiration
*
* @param jwtToken the JWT token
* @return the query response
*/
public QueryResponse parseJwtToken(String jwtToken) {
/*
* Removes signature, because of z/OSMF we don't have key to verify certificate and
* we just need to read claim. Verification is realized via REST call to z/OSMF.
* JWT library doesn't parse signed key without verification.
*/
final String withoutSign = removeSign(jwtToken);
// parse to claims and construct QueryResponse
try {
Claims claims = Jwts.parser()
.parseClaimsJwt(withoutSign)
.getBody();
return new QueryResponse(
claims.get(DOMAIN_CLAIM_NAME, String.class),
claims.getSubject(),
claims.getIssuedAt(),
claims.getExpiration(),
QueryResponse.Source.valueByIssuer(claims.getIssuer())
);
} catch (RuntimeException exception) {
throw handleJwtParserException(exception);
}
}
public static RequestUserDTO getConnUser(HttpServletRequest request) {
String token = request.getHeader(HEADER_STRING);
if (token == null) {
token = getTokenFromCookis(request);
}
if (token != null) {
// 解析 Token
Claims claims = Jwts.parser().setSigningKey(SECRET)
.parseClaimsJws(token).getBody();
return new RequestUserDTO(
claims.get("DomainId", String.class),
claims.get("UserId", String.class),
claims.get("OrgUnitId", String.class));
}
return new RequestUserDTO();
}
public static AuthUser parseJWT(String jwt) {
if (jwt.split("\\.").length == 3) {
// String head = jwt.split("\\.")[0];
// String payload = jwt.split("\\.")[1];
String sign = jwt.split("\\.")[2];
// JwsHeader claim1 = Jwts.parser().setSigningKey(DatatypeConverter.parseBase64Binary(CONSTANT.SECRET_KEY)).parseClaimsJws(jwt).getHeader();
Claims claims = Jwts.parser().setSigningKey(DatatypeConverter.parseBase64Binary(CONSTANT.SECRET_KEY)).parseClaimsJws(jwt).getBody();
String newSign = createJWT(JSONObject.toJSONString(claims)).split("\\.")[2];
if (Common.isEquals(newSign, sign)) {
// log.info("数据一致");
// log.info(String.valueOf(claims.get("userId")));
// log.info((String) claims.get("userName"));
// log.info((String) claims.get("userNickName"));
// log.info((String) claims.get("expireTime"));
AuthUser authUser = new AuthUser((Integer) claims.get("userId"), (String) claims.get("userName"),
(String) claims.get("userNickName"), Timestamp.valueOf((String) claims.get("expireTime")));
return authUser;
}
return null;
} else {
return null;
}
}
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
String path = exchange.getRequest().getURI().getPath();
if (isSkip(path)) {
return chain.filter(exchange);
}
ServerHttpResponse resp = exchange.getResponse();
String headerToken = exchange.getRequest().getHeaders().getFirst(AuthProvider.AUTH_KEY);
String paramToken = exchange.getRequest().getQueryParams().getFirst(AuthProvider.AUTH_KEY);
if (StringUtils.isAllBlank(headerToken, paramToken)) {
return unAuth(resp, "缺失令牌,鉴权失败");
}
String auth = StringUtils.isBlank(headerToken) ? paramToken : headerToken;
String token = JwtUtil.getToken(auth);
Claims claims = JwtUtil.parseJWT(token);
if (claims == null) {
return unAuth(resp, "请求未授权");
}
return chain.filter(exchange);
}
/**
* 获取Claims
*
* @param request request
* @return Claims
*/
public static Claims getClaims(HttpServletRequest request) {
String auth = request.getHeader(SecureUtil.HEADER);
if (StringUtil.isNotBlank(auth) && auth.length() > AUTH_LENGTH) {
String headStr = auth.substring(0, 6).toLowerCase();
if (headStr.compareTo(SecureUtil.BEARER) == 0) {
auth = auth.substring(7);
return SecureUtil.parseJWT(auth);
}
} else {
String parameter = request.getParameter(SecureUtil.HEADER);
if (StringUtil.isNotBlank(parameter)) {
return SecureUtil.parseJWT(parameter);
}
}
return null;
}
/**
* 解析token
*
* @param token
* @return
* @throws Exception
*/
public static AuthTokenDetails parseToken(String token) throws Exception {
Claims claims = Jwts.parser().setSigningKey(SECRET_KEY).parseClaimsJws(token).getBody();
String userId = claims.getSubject();
String appId = (String) claims.get(APP_ID_FIELD);
String organizationId = (String) claims.get(ORGANIZATION_ID_FIELD);
String roleId = (String) claims.get(ROLE_ID_FIELD);
String roleType = (String) claims.get(ROLE_TYPE_FIELD);
String language = (String) claims.get(LANGUAGE_FIELD);
Date expirationDate = claims.getExpiration();
AuthTokenDetails authTokenDetails = new AuthTokenDetails();
authTokenDetails.setUserId(Long.valueOf(userId));
authTokenDetails.setAppId(appId);
authTokenDetails.setOrganizationId(Long.valueOf(organizationId));
authTokenDetails.setRoleId(roleId == null ? null : Long.valueOf(roleId));
authTokenDetails.setRoleType(RoleTypeEnum.valueOf(roleType));
authTokenDetails.setExpirationDate(expirationDate);
authTokenDetails.setLanguage(language);
return authTokenDetails;
}
/**
* 使用HS256签名算法和生成的signingKey最终的Token,claims中是有效载荷
*
* @param userName = sub JWT面向的用户 (User)
* @param clientId = aud 接受JWT的一方 (Client)
* @param expiration = exp 过期时间
* @param issuedAt = iat 签发时间
* @return
*/
public static String createJavaWebToken(Long userId, String userName, String clientId, String scope,
Date expiration, Date issuedAt) {
Claims claims = Jwts.claims();
claims.put(USER_ID_KEY, userId);
claims.put(USER_NAME_KEY, userName);
claims.put(CLIENT_ID_KEY, clientId);
claims.put(SCOPE_KEY, scope);
String token = Jwts.builder()
.setClaims(claims)
//JWT的签发者
//.setIssuer("oauth")
//.setSubject(userId)
//.setAudience(clientId)
.setExpiration(expiration)
.setIssuedAt(issuedAt)
.signWith(SignatureAlgorithm.HS256, getKeyInstance())
.compact();
return token;
}
/**
* 根据token 获取用户ID
* @param token
* @return
*/
private int getUserIdFromToken(String token) {
int userId;
try {
final Claims claims = getClaimsFromToken(token);
userId = Integer.parseInt(String.valueOf(claims.get(CLAIM_KEY_USER_ID)));
} catch (Exception e) {
userId = 0;
}
return userId;
}
/**
* 根据token 获取用户名
* @param token
* @return
*/
public String getUsernameFromToken(String token) {
String username;
try {
final Claims claims = getClaimsFromToken(token);
username = claims.getSubject();
} catch (Exception e) {
username = null;
}
return username;
}
/**
* 根据token 获取生成时间
* @param token
* @return
*/
public Date getCreatedDateFromToken(String token) {
Date created;
try {
final Claims claims = getClaimsFromToken(token);
created = claims.getIssuedAt();
} catch (Exception e) {
created = null;
}
return created;
}
/**
* 刷新令牌
*
* @param token 原令牌
* @return 新令牌
*/
public String refreshToken(String token) {
String refreshedToken;
try {
final Claims claims = getClaimsFromToken(token);
refreshedToken = generateAccessToken(claims.getSubject(), claims);
} catch (Exception e) {
refreshedToken = null;
}
return refreshedToken;
}
/***
* 解析token 信息
* @param token
* @return
*/
private Claims getClaimsFromToken(String token) {
Claims claims;
try {
claims = Jwts.parser()
.setSigningKey(secret)
.parseClaimsJws(token)
.getBody();
} catch (Exception e) {
claims = null;
}
return claims;
}
/**
* 解析 token,
* 利用 jjwt 提供的parser传入秘钥,
*
* @param token token
* @return 数据声明 Map<String, Object>
*/
private Claims getClaimByToken(String token) {
try {
return Jwts.parser()
.setSigningKey(secret)
.parseClaimsJws(token)
.getBody();
} catch (Exception e) {
return null;
}
}
public String getUsernameFromToken(String token) {
String username;
try {
final Claims claims = this.getAllClaimsFromToken(token);
username = claims.getSubject();
} catch (Exception e) {
username = null;
}
return username;
}
@Test
public void doLoginWithValidBodyLoginRequest() {
LoginRequest loginRequest = new LoginRequest(USERNAME, PASSWORD);
Cookie cookie = given()
.contentType(JSON)
.body(loginRequest)
.when()
.post(String.format("%s://%s:%d%s%s%s", SCHEME, HOST, PORT, CATALOG_PREFIX, CATALOG_SERVICE_ID,LOGIN_ENDPOINT))
.then()
.statusCode(is(SC_NO_CONTENT))
.cookie(COOKIE_NAME, not(isEmptyString()))
.extract().detailedCookie(COOKIE_NAME);
assertTrue(cookie.isHttpOnly());
assertThat(cookie.getValue(), is(notNullValue()));
assertThat(cookie.getMaxAge(), is(-1));
int i = cookie.getValue().lastIndexOf('.');
String untrustedJwtString = cookie.getValue().substring(0, i + 1);
Claims claims = Jwts.parser()
.parseClaimsJwt(untrustedJwtString)
.getBody();
assertThat(claims.getId(), not(isEmptyString()));
assertThat(claims.getSubject(), is(USERNAME));
}
@Override
public <ReqT, RespT> ServerCall.Listener<ReqT> interceptCall(ServerCall<ReqT, RespT> serverCall,
Metadata metadata, ServerCallHandler<ReqT, RespT> serverCallHandler) {
String value = metadata.get(Constant.AUTHORIZATION_METADATA_KEY);
Status status = Status.OK;
if (value == null) {
status = Status.UNAUTHENTICATED.withDescription("Authorization token is missing");
} else if (!value.startsWith(Constant.BEARER_TYPE)) {
status = Status.UNAUTHENTICATED.withDescription("Unknown authorization type");
} else {
Jws<Claims> claims = null;
// remove authorization type prefix
String token = value.substring(Constant.BEARER_TYPE.length()).trim();
try {
// verify token signature and parse claims
claims = parser.parseClaimsJws(token);
} catch (JwtException e) {
status = Status.UNAUTHENTICATED.withDescription(e.getMessage()).withCause(e);
}
if (claims != null) {
// set client id into current context
Context ctx = Context.current()
.withValue(Constant.CLIENT_ID_CONTEXT_KEY, claims.getBody().getSubject());
return Contexts.interceptCall(ctx, serverCall, metadata, serverCallHandler);
}
}
serverCall.close(status, new Metadata());
return new ServerCall.Listener<ReqT>() {
// noop
};
}
/**
* 功能描述: 根据登陆token获取登陆信息
*
* @param
* @return
* @auther yandanyang
* @date 2018/9/12 0012 上午 10:11
*/
public RequestTokenBO getEmployeeTokenInfo(String token) {
Long employeeId = -1L;
try {
Claims claims = Jwts.parser().setSigningKey(jwtKey).parseClaimsJws(token).getBody();
String idStr = claims.get(CLAIM_ID_KEY).toString();
employeeId = Long.valueOf(idStr);
} catch (Exception e) {
log.error("getEmployeeTokenInfo error:{}", e);
return null;
}
EmployeeBO employeeBO = employeeService.getById(employeeId);
if (employeeBO == null) {
return null;
}
if (EmployeeStatusEnum.DISABLED.getValue().equals(employeeBO.getIsDisabled())) {
return null;
}
if (JudgeEnum.YES.equals(employeeBO.getIsLeave())) {
return null;
}
if (JudgeEnum.YES.equals(employeeBO.getIsDelete())) {
return null;
}
return new RequestTokenBO(employeeBO);
}
public String createToken(String username, List<Role> roles) {
Claims claims = Jwts.claims().setSubject(username);
claims.put("auth", roles.stream().map(s -> new SimpleGrantedAuthority(s.getAuthority())).filter(Objects::nonNull).collect(Collectors.toList()));
Date now = new Date();
Date validity = new Date(now.getTime() + validityInMilliseconds);
return Jwts.builder()//
.setClaims(claims)//
.setIssuedAt(now)//
.setExpiration(validity)//
.signWith(SignatureAlgorithm.HS256, secretKey)//
.compact();
}
public String getAudienceFromToken(String token) {
String audience;
try {
final Claims claims = getClaimsFromToken(token);
audience = (String) claims.get(CLAIM_KEY_AUDIENCE);
} catch (Exception e) {
audience = null;
}
return audience;
}
/**
* Validates and returns the claims of given JWS
*
* @param token compact JWS (JSON Web Signature)
* @return {@link Claims} . Returns <code>null</code> if it fails to verify/expires the JWT.
*/
public @Nullable Claims getClaims(@Nonnull String token) {
Claims claims;
try {
claims =
Jwts.parser().setSigningKey(String.valueOf(secretKey)).parseClaimsJws(token).getBody();
} catch (JwtException e) {
log.debug("JWT token parser error.", e);
claims = null;
}
return claims;
}
public JwsToUserDetailsConverter(Function<String, Claims> claimsExtractor,
Function<Claims, User> claimsUserFactory,
Function<Claims, Collection<? extends GrantedAuthority>> authoritiesResolver) {
Assert.notNull(claimsExtractor, "claimsExtractor cannot be null.");
Assert.notNull(claimsUserFactory, "claimsUserFactory cannot be null.");
this.claimsExtractor = claimsExtractor;
this.claimsUserFactory = claimsUserFactory;
this.authoritiesResolver = authoritiesResolver;
}
/**
* 刷新令牌
*
* @param token
* @return
*/
public static String refreshToken(String token) {
String refreshedToken;
try {
Claims claims = getClaimsFromToken(token);
claims.put(CREATED, new Date());
refreshedToken = generateToken(claims);
} catch (Exception e) {
refreshedToken = null;
}
return refreshedToken;
}