mirror of
https://github.com/tencentmusic/supersonic.git
synced 2025-12-11 12:07:42 +00:00
[improvement][auth] Optimize the TokenService-related code (#1835)
This commit is contained in:
@@ -1,7 +1,5 @@
|
||||
package com.tencent.supersonic.auth.authentication.adaptor;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Sets;
|
||||
import com.tencent.supersonic.auth.api.authentication.adaptor.UserAdaptor;
|
||||
@@ -10,18 +8,21 @@ import com.tencent.supersonic.auth.api.authentication.pojo.UserWithPassword;
|
||||
import com.tencent.supersonic.auth.api.authentication.request.UserReq;
|
||||
import com.tencent.supersonic.auth.authentication.persistence.dataobject.UserDO;
|
||||
import com.tencent.supersonic.auth.authentication.persistence.repository.UserRepository;
|
||||
import com.tencent.supersonic.auth.authentication.utils.UserTokenUtils;
|
||||
import com.tencent.supersonic.auth.authentication.utils.TokenService;
|
||||
import com.tencent.supersonic.common.pojo.User;
|
||||
import com.tencent.supersonic.common.util.AESEncryptionUtil;
|
||||
import com.tencent.supersonic.common.util.ContextUtils;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.BeanUtils;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/** DefaultUserAdaptor provides a default method to obtain user and organization information */
|
||||
/**
|
||||
* DefaultUserAdaptor provides a default method to obtain user and organization information
|
||||
*/
|
||||
@Slf4j
|
||||
public class DefaultUserAdaptor implements UserAdaptor {
|
||||
|
||||
@@ -88,17 +89,17 @@ public class DefaultUserAdaptor implements UserAdaptor {
|
||||
|
||||
@Override
|
||||
public String login(UserReq userReq, HttpServletRequest request) {
|
||||
UserTokenUtils userTokenUtils = ContextUtils.getBean(UserTokenUtils.class);
|
||||
String appKey = userTokenUtils.getAppKey(request);
|
||||
TokenService tokenService = ContextUtils.getBean(TokenService.class);
|
||||
String appKey = tokenService.getAppKey(request);
|
||||
return login(userReq, appKey);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String login(UserReq userReq, String appKey) {
|
||||
UserTokenUtils userTokenUtils = ContextUtils.getBean(UserTokenUtils.class);
|
||||
TokenService tokenService = ContextUtils.getBean(TokenService.class);
|
||||
try {
|
||||
UserWithPassword user = getUserWithPassword(userReq);
|
||||
return userTokenUtils.generateToken(user, appKey);
|
||||
return tokenService.generateToken(UserWithPassword.convert(user), appKey);
|
||||
} catch (Exception e) {
|
||||
log.error("", e);
|
||||
throw new RuntimeException("password encrypt error, please try again");
|
||||
|
||||
@@ -1,11 +1,9 @@
|
||||
package com.tencent.supersonic.auth.authentication.interceptor;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
import com.tencent.supersonic.auth.api.authentication.config.AuthenticationConfig;
|
||||
import com.tencent.supersonic.auth.api.authentication.constant.UserConstants;
|
||||
import com.tencent.supersonic.auth.authentication.service.UserServiceImpl;
|
||||
import com.tencent.supersonic.auth.authentication.utils.UserTokenUtils;
|
||||
import com.tencent.supersonic.auth.authentication.utils.TokenService;
|
||||
import com.tencent.supersonic.common.util.S2ThreadContext;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.catalina.connector.RequestFacade;
|
||||
@@ -15,6 +13,7 @@ import org.springframework.util.CollectionUtils;
|
||||
import org.springframework.web.multipart.support.StandardMultipartHttpServletRequest;
|
||||
import org.springframework.web.servlet.HandlerInterceptor;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
@@ -26,7 +25,7 @@ public abstract class AuthenticationInterceptor implements HandlerInterceptor {
|
||||
|
||||
protected UserServiceImpl userServiceImpl;
|
||||
|
||||
protected UserTokenUtils userTokenUtils;
|
||||
protected TokenService tokenService;
|
||||
|
||||
protected S2ThreadContext s2ThreadContext;
|
||||
|
||||
|
||||
@@ -1,22 +1,30 @@
|
||||
package com.tencent.supersonic.auth.authentication.interceptor;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import com.tencent.supersonic.auth.api.authentication.annotation.AuthenticationIgnore;
|
||||
import com.tencent.supersonic.auth.api.authentication.config.AuthenticationConfig;
|
||||
import com.tencent.supersonic.auth.api.authentication.pojo.UserWithPassword;
|
||||
import com.tencent.supersonic.auth.authentication.service.UserServiceImpl;
|
||||
import com.tencent.supersonic.auth.authentication.utils.UserTokenUtils;
|
||||
import com.tencent.supersonic.auth.authentication.utils.TokenService;
|
||||
import com.tencent.supersonic.common.pojo.User;
|
||||
import com.tencent.supersonic.common.pojo.exception.AccessException;
|
||||
import com.tencent.supersonic.common.util.ContextUtils;
|
||||
import com.tencent.supersonic.common.util.S2ThreadContext;
|
||||
import com.tencent.supersonic.common.util.ThreadContext;
|
||||
import io.jsonwebtoken.Claims;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.web.method.HandlerMethod;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Optional;
|
||||
|
||||
import static com.tencent.supersonic.auth.api.authentication.constant.UserConstants.TOKEN_IS_ADMIN;
|
||||
import static com.tencent.supersonic.auth.api.authentication.constant.UserConstants.TOKEN_USER_DISPLAY_NAME;
|
||||
import static com.tencent.supersonic.auth.api.authentication.constant.UserConstants.TOKEN_USER_EMAIL;
|
||||
import static com.tencent.supersonic.auth.api.authentication.constant.UserConstants.TOKEN_USER_ID;
|
||||
import static com.tencent.supersonic.auth.api.authentication.constant.UserConstants.TOKEN_USER_NAME;
|
||||
import static com.tencent.supersonic.auth.api.authentication.constant.UserConstants.TOKEN_USER_PASSWORD;
|
||||
|
||||
@Slf4j
|
||||
public class DefaultAuthenticationInterceptor extends AuthenticationInterceptor {
|
||||
@@ -26,7 +34,7 @@ public class DefaultAuthenticationInterceptor extends AuthenticationInterceptor
|
||||
Object handler) throws AccessException {
|
||||
authenticationConfig = ContextUtils.getBean(AuthenticationConfig.class);
|
||||
userServiceImpl = ContextUtils.getBean(UserServiceImpl.class);
|
||||
userTokenUtils = ContextUtils.getBean(UserTokenUtils.class);
|
||||
tokenService = ContextUtils.getBean(TokenService.class);
|
||||
s2ThreadContext = ContextUtils.getBean(S2ThreadContext.class);
|
||||
if (!authenticationConfig.isEnabled()) {
|
||||
setFakerUser(request);
|
||||
@@ -58,7 +66,7 @@ public class DefaultAuthenticationInterceptor extends AuthenticationInterceptor
|
||||
return true;
|
||||
}
|
||||
|
||||
UserWithPassword user = userTokenUtils.getUserWithPassword(request);
|
||||
UserWithPassword user = getUserWithPassword(request);
|
||||
if (user != null) {
|
||||
setContext(user.getName(), request);
|
||||
return true;
|
||||
@@ -67,7 +75,7 @@ public class DefaultAuthenticationInterceptor extends AuthenticationInterceptor
|
||||
}
|
||||
|
||||
private void setFakerUser(HttpServletRequest request) {
|
||||
String token = userTokenUtils.generateAdminToken(request);
|
||||
String token = generateAdminToken(request);
|
||||
reflectSetParam(request, authenticationConfig.getTokenHttpHeaderKey(), token);
|
||||
setContext(User.getDefaultUser().getName(), request);
|
||||
}
|
||||
@@ -78,4 +86,30 @@ public class DefaultAuthenticationInterceptor extends AuthenticationInterceptor
|
||||
.userName(userName).build();
|
||||
s2ThreadContext.set(threadContext);
|
||||
}
|
||||
|
||||
public String generateAdminToken(HttpServletRequest request) {
|
||||
UserWithPassword admin = new UserWithPassword("admin");
|
||||
admin.setId(1L);
|
||||
admin.setName("admin");
|
||||
admin.setPassword("c3VwZXJzb25pY0BiaWNvbdktJJYWw6A3rEmBUPzbn/6DNeYnD+y3mAwDKEMS3KVT");
|
||||
admin.setDisplayName("admin");
|
||||
admin.setIsAdmin(1);
|
||||
return tokenService.generateToken(UserWithPassword.convert(admin), request);
|
||||
}
|
||||
|
||||
public UserWithPassword getUserWithPassword(HttpServletRequest request) {
|
||||
final Optional<Claims> claimsOptional = tokenService.getClaims(request);
|
||||
if (!claimsOptional.isPresent()) {
|
||||
return null;
|
||||
}
|
||||
Claims claims = claimsOptional.get();
|
||||
Long userId = Long.parseLong(claims.getOrDefault(TOKEN_USER_ID, 0).toString());
|
||||
String userName = String.valueOf(claims.get(TOKEN_USER_NAME));
|
||||
String email = String.valueOf(claims.get(TOKEN_USER_EMAIL));
|
||||
String displayName = String.valueOf(claims.get(TOKEN_USER_DISPLAY_NAME));
|
||||
String password = String.valueOf(claims.get(TOKEN_USER_PASSWORD));
|
||||
Integer isAdmin = claims.get(TOKEN_IS_ADMIN) == null ? 0
|
||||
: Integer.parseInt(claims.get(TOKEN_IS_ADMIN).toString());
|
||||
return UserWithPassword.get(userId, userName, displayName, email, password, isAdmin);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,20 +1,23 @@
|
||||
package com.tencent.supersonic.auth.authentication.strategy;
|
||||
|
||||
import com.tencent.supersonic.auth.api.authentication.constant.UserConstants;
|
||||
import com.tencent.supersonic.auth.api.authentication.service.UserStrategy;
|
||||
import com.tencent.supersonic.auth.authentication.utils.TokenService;
|
||||
import com.tencent.supersonic.common.pojo.User;
|
||||
import io.jsonwebtoken.Claims;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import com.tencent.supersonic.auth.api.authentication.service.UserStrategy;
|
||||
import com.tencent.supersonic.auth.authentication.utils.UserTokenUtils;
|
||||
import com.tencent.supersonic.common.pojo.User;
|
||||
import org.springframework.stereotype.Service;
|
||||
import java.util.Optional;
|
||||
|
||||
@Service
|
||||
public class HttpHeaderUserStrategy implements UserStrategy {
|
||||
|
||||
private final UserTokenUtils userTokenUtils;
|
||||
private final TokenService tokenService;
|
||||
|
||||
public HttpHeaderUserStrategy(UserTokenUtils userTokenUtils) {
|
||||
this.userTokenUtils = userTokenUtils;
|
||||
public HttpHeaderUserStrategy(TokenService tokenService) {
|
||||
this.tokenService = tokenService;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -24,11 +27,33 @@ public class HttpHeaderUserStrategy implements UserStrategy {
|
||||
|
||||
@Override
|
||||
public User findUser(HttpServletRequest request, HttpServletResponse response) {
|
||||
return userTokenUtils.getUser(request);
|
||||
return getUser(request);
|
||||
}
|
||||
|
||||
@Override
|
||||
public User findUser(String token, String appKey) {
|
||||
return userTokenUtils.getUser(token, appKey);
|
||||
return getUser(token, appKey);
|
||||
}
|
||||
|
||||
public User getUser(HttpServletRequest request) {
|
||||
final Optional<Claims> claimsOptional = tokenService.getClaims(request);
|
||||
return claimsOptional.map(this::getUser).orElse(User.getVisitUser());
|
||||
}
|
||||
|
||||
public User getUser(String token, String appKey) {
|
||||
final Optional<Claims> claimsOptional = tokenService.getClaims(token, appKey);
|
||||
return claimsOptional.map(this::getUser).orElse(User.getVisitUser());
|
||||
}
|
||||
|
||||
private User getUser(Claims claims) {
|
||||
Long userId =
|
||||
Long.parseLong(claims.getOrDefault(UserConstants.TOKEN_USER_ID, 0).toString());
|
||||
String userName = String.valueOf(claims.get(UserConstants.TOKEN_USER_NAME));
|
||||
String email = String.valueOf(claims.get(UserConstants.TOKEN_USER_EMAIL));
|
||||
String displayName = String.valueOf(claims.get(UserConstants.TOKEN_USER_DISPLAY_NAME));
|
||||
Integer isAdmin = claims.get(UserConstants.TOKEN_IS_ADMIN) == null ? 0
|
||||
: Integer.parseInt(claims.get(UserConstants.TOKEN_IS_ADMIN).toString());
|
||||
return User.get(userId, userName, displayName, email, isAdmin);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,96 @@
|
||||
package com.tencent.supersonic.auth.authentication.utils;
|
||||
|
||||
import com.tencent.supersonic.auth.api.authentication.config.AuthenticationConfig;
|
||||
import com.tencent.supersonic.common.pojo.exception.AccessException;
|
||||
import io.jsonwebtoken.Claims;
|
||||
import io.jsonwebtoken.Jwts;
|
||||
import io.jsonwebtoken.SignatureAlgorithm;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.crypto.spec.SecretKeySpec;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Date;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
|
||||
import static com.tencent.supersonic.auth.api.authentication.constant.UserConstants.TOKEN_CREATE_TIME;
|
||||
import static com.tencent.supersonic.auth.api.authentication.constant.UserConstants.TOKEN_PREFIX;
|
||||
import static com.tencent.supersonic.auth.api.authentication.constant.UserConstants.TOKEN_USER_NAME;
|
||||
|
||||
@Slf4j
|
||||
@Component
|
||||
public class TokenService {
|
||||
|
||||
private AuthenticationConfig authenticationConfig;
|
||||
|
||||
public TokenService(AuthenticationConfig authenticationConfig) {
|
||||
this.authenticationConfig = authenticationConfig;
|
||||
}
|
||||
|
||||
public String generateToken(Map<String, Object> claims, HttpServletRequest request) {
|
||||
String appKey = getAppKey(request);
|
||||
return generateToken(claims, appKey);
|
||||
}
|
||||
|
||||
public String generateToken(Map<String, Object> claims, String appKey) {
|
||||
return toTokenString(claims, appKey);
|
||||
}
|
||||
|
||||
private String toTokenString(Map<String, Object> claims, String appKey) {
|
||||
Long tokenTimeout = authenticationConfig.getTokenTimeout();
|
||||
long expiration = Long.parseLong(claims.get(TOKEN_CREATE_TIME) + "") + tokenTimeout;
|
||||
Date expirationDate = new Date(expiration);
|
||||
String tokenSecret = getTokenSecret(appKey);
|
||||
|
||||
return Jwts.builder().setClaims(claims).setSubject(claims.get(TOKEN_USER_NAME).toString())
|
||||
.setExpiration(expirationDate)
|
||||
.signWith(new SecretKeySpec(tokenSecret.getBytes(StandardCharsets.UTF_8),
|
||||
SignatureAlgorithm.HS512.getJcaName()), SignatureAlgorithm.HS512)
|
||||
.compact();
|
||||
}
|
||||
|
||||
private String getTokenSecret(String appKey) {
|
||||
Map<String, String> appKeyToSecretMap = authenticationConfig.getAppKeyToSecretMap();
|
||||
String secret = appKeyToSecretMap.get(appKey);
|
||||
if (StringUtils.isBlank(secret)) {
|
||||
throw new AccessException("get secret from appKey failed :" + appKey);
|
||||
}
|
||||
return secret;
|
||||
}
|
||||
|
||||
public Optional<Claims> getClaims(HttpServletRequest request) {
|
||||
String token = request.getHeader(authenticationConfig.getTokenHttpHeaderKey());
|
||||
String appKey = getAppKey(request);
|
||||
return getClaims(token, appKey);
|
||||
}
|
||||
|
||||
public Optional<Claims> getClaims(String token, String appKey) {
|
||||
try {
|
||||
String tokenSecret = getTokenSecret(appKey);
|
||||
Claims claims =
|
||||
Jwts.parser().setSigningKey(tokenSecret.getBytes(StandardCharsets.UTF_8))
|
||||
.build().parseClaimsJws(getTokenString(token)).getBody();
|
||||
return Optional.of(claims);
|
||||
} catch (Exception e) {
|
||||
log.info("can not getClaims from appKey:{} token:{}, please login", appKey, token);
|
||||
}
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
private static String getTokenString(String token) {
|
||||
return token.startsWith(TOKEN_PREFIX)
|
||||
? token.substring(token.indexOf(TOKEN_PREFIX) + TOKEN_PREFIX.length()).trim()
|
||||
: token.trim();
|
||||
}
|
||||
|
||||
public String getAppKey(HttpServletRequest request) {
|
||||
String appKey = request.getHeader(authenticationConfig.getTokenHttpHeaderAppKey());
|
||||
if (StringUtils.isBlank(appKey)) {
|
||||
appKey = authenticationConfig.getTokenDefaultAppKey();
|
||||
}
|
||||
return appKey;
|
||||
}
|
||||
}
|
||||
@@ -1,167 +0,0 @@
|
||||
package com.tencent.supersonic.auth.authentication.utils;
|
||||
|
||||
import javax.crypto.spec.SecretKeySpec;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
import com.tencent.supersonic.auth.api.authentication.config.AuthenticationConfig;
|
||||
import com.tencent.supersonic.auth.api.authentication.pojo.UserWithPassword;
|
||||
import com.tencent.supersonic.common.pojo.User;
|
||||
import com.tencent.supersonic.common.pojo.exception.AccessException;
|
||||
import io.jsonwebtoken.Claims;
|
||||
import io.jsonwebtoken.Jwts;
|
||||
import io.jsonwebtoken.SignatureAlgorithm;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
|
||||
import static com.tencent.supersonic.auth.api.authentication.constant.UserConstants.TOKEN_CREATE_TIME;
|
||||
import static com.tencent.supersonic.auth.api.authentication.constant.UserConstants.TOKEN_IS_ADMIN;
|
||||
import static com.tencent.supersonic.auth.api.authentication.constant.UserConstants.TOKEN_PREFIX;
|
||||
import static com.tencent.supersonic.auth.api.authentication.constant.UserConstants.TOKEN_USER_DISPLAY_NAME;
|
||||
import static com.tencent.supersonic.auth.api.authentication.constant.UserConstants.TOKEN_USER_EMAIL;
|
||||
import static com.tencent.supersonic.auth.api.authentication.constant.UserConstants.TOKEN_USER_ID;
|
||||
import static com.tencent.supersonic.auth.api.authentication.constant.UserConstants.TOKEN_USER_NAME;
|
||||
import static com.tencent.supersonic.auth.api.authentication.constant.UserConstants.TOKEN_USER_PASSWORD;
|
||||
|
||||
@Slf4j
|
||||
@Component
|
||||
public class UserTokenUtils {
|
||||
|
||||
private AuthenticationConfig authenticationConfig;
|
||||
|
||||
public UserTokenUtils(AuthenticationConfig authenticationConfig) {
|
||||
this.authenticationConfig = authenticationConfig;
|
||||
}
|
||||
|
||||
public String generateToken(UserWithPassword user, HttpServletRequest request) {
|
||||
String appKey = getAppKey(request);
|
||||
return generateToken(user, appKey);
|
||||
}
|
||||
|
||||
public String generateToken(UserWithPassword user, String appKey) {
|
||||
Map<String, Object> claims = new HashMap<>(5);
|
||||
claims.put(TOKEN_USER_ID, user.getId());
|
||||
claims.put(TOKEN_USER_NAME, StringUtils.isEmpty(user.getName()) ? "" : user.getName());
|
||||
claims.put(TOKEN_USER_PASSWORD,
|
||||
StringUtils.isEmpty(user.getPassword()) ? "" : user.getPassword());
|
||||
claims.put(TOKEN_USER_DISPLAY_NAME, user.getDisplayName());
|
||||
claims.put(TOKEN_CREATE_TIME, System.currentTimeMillis());
|
||||
claims.put(TOKEN_IS_ADMIN, user.getIsAdmin());
|
||||
return generate(claims, appKey);
|
||||
}
|
||||
|
||||
public String generateAdminToken(HttpServletRequest request) {
|
||||
UserWithPassword admin = new UserWithPassword("admin");
|
||||
admin.setId(1L);
|
||||
admin.setName("admin");
|
||||
admin.setPassword("c3VwZXJzb25pY0BiaWNvbdktJJYWw6A3rEmBUPzbn/6DNeYnD+y3mAwDKEMS3KVT");
|
||||
admin.setDisplayName("admin");
|
||||
admin.setIsAdmin(1);
|
||||
return generateToken(admin, request);
|
||||
}
|
||||
|
||||
public User getUser(HttpServletRequest request) {
|
||||
String token = request.getHeader(authenticationConfig.getTokenHttpHeaderKey());
|
||||
final Optional<Claims> claimsOptional = getClaims(token, request);
|
||||
return claimsOptional.map(this::getUser).orElse(User.getVisitUser());
|
||||
}
|
||||
|
||||
public User getUser(String token, String appKey) {
|
||||
final Optional<Claims> claimsOptional = getClaims(token, appKey);
|
||||
return claimsOptional.map(this::getUser).orElse(User.getVisitUser());
|
||||
}
|
||||
|
||||
private User getUser(Claims claims) {
|
||||
Long userId = Long.parseLong(claims.getOrDefault(TOKEN_USER_ID, 0).toString());
|
||||
String userName = String.valueOf(claims.get(TOKEN_USER_NAME));
|
||||
String email = String.valueOf(claims.get(TOKEN_USER_EMAIL));
|
||||
String displayName = String.valueOf(claims.get(TOKEN_USER_DISPLAY_NAME));
|
||||
Integer isAdmin = claims.get(TOKEN_IS_ADMIN) == null ? 0
|
||||
: Integer.parseInt(claims.get(TOKEN_IS_ADMIN).toString());
|
||||
return User.get(userId, userName, displayName, email, isAdmin);
|
||||
}
|
||||
|
||||
public UserWithPassword getUserWithPassword(HttpServletRequest request) {
|
||||
String token = request.getHeader(authenticationConfig.getTokenHttpHeaderKey());
|
||||
if (StringUtils.isBlank(token)) {
|
||||
return null;
|
||||
}
|
||||
final Optional<Claims> claimsOptional = getClaims(token, request);
|
||||
if (!claimsOptional.isPresent()) {
|
||||
return null;
|
||||
}
|
||||
final Claims claims = claimsOptional.get();
|
||||
Long userId = Long.parseLong(claims.getOrDefault(TOKEN_USER_ID, 0).toString());
|
||||
String userName = String.valueOf(claims.get(TOKEN_USER_NAME));
|
||||
String email = String.valueOf(claims.get(TOKEN_USER_EMAIL));
|
||||
String displayName = String.valueOf(claims.get(TOKEN_USER_DISPLAY_NAME));
|
||||
String password = String.valueOf(claims.get(TOKEN_USER_PASSWORD));
|
||||
Integer isAdmin = claims.get(TOKEN_IS_ADMIN) == null ? 0
|
||||
: Integer.parseInt(claims.get(TOKEN_IS_ADMIN).toString());
|
||||
return UserWithPassword.get(userId, userName, displayName, email, password, isAdmin);
|
||||
}
|
||||
|
||||
private Optional<Claims> getClaims(String token, HttpServletRequest request) {
|
||||
String appKey = getAppKey(request);
|
||||
return getClaims(token, appKey);
|
||||
}
|
||||
|
||||
private Optional<Claims> getClaims(String token, String appKey) {
|
||||
try {
|
||||
String tokenSecret = getTokenSecret(appKey);
|
||||
Claims claims =
|
||||
Jwts.parser().setSigningKey(tokenSecret.getBytes(StandardCharsets.UTF_8))
|
||||
.build().parseClaimsJws(getTokenString(token)).getBody();
|
||||
return Optional.of(claims);
|
||||
} catch (Exception e) {
|
||||
log.info("can not getClaims from appKey:{} token:{}, please login", appKey, token);
|
||||
}
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
private static String getTokenString(String token) {
|
||||
return token.startsWith(TOKEN_PREFIX)
|
||||
? token.substring(token.indexOf(TOKEN_PREFIX) + TOKEN_PREFIX.length()).trim()
|
||||
: token.trim();
|
||||
}
|
||||
|
||||
private String generate(Map<String, Object> claims, String appKey) {
|
||||
return toTokenString(claims, appKey);
|
||||
}
|
||||
|
||||
private String toTokenString(Map<String, Object> claims, String appKey) {
|
||||
Long tokenTimeout = authenticationConfig.getTokenTimeout();
|
||||
long expiration = Long.parseLong(claims.get(TOKEN_CREATE_TIME) + "") + tokenTimeout;
|
||||
Date expirationDate = new Date(expiration);
|
||||
String tokenSecret = getTokenSecret(appKey);
|
||||
|
||||
return Jwts.builder().setClaims(claims).setSubject(claims.get(TOKEN_USER_NAME).toString())
|
||||
.setExpiration(expirationDate)
|
||||
.signWith(new SecretKeySpec(tokenSecret.getBytes(StandardCharsets.UTF_8),
|
||||
SignatureAlgorithm.HS512.getJcaName()), SignatureAlgorithm.HS512)
|
||||
.compact();
|
||||
}
|
||||
|
||||
private String getTokenSecret(String appKey) {
|
||||
Map<String, String> appKeyToSecretMap = authenticationConfig.getAppKeyToSecretMap();
|
||||
String secret = appKeyToSecretMap.get(appKey);
|
||||
if (StringUtils.isBlank(secret)) {
|
||||
throw new AccessException("get secret from appKey failed :" + appKey);
|
||||
}
|
||||
return secret;
|
||||
}
|
||||
|
||||
public String getAppKey(HttpServletRequest request) {
|
||||
String appKey = request.getHeader(authenticationConfig.getTokenHttpHeaderAppKey());
|
||||
if (StringUtils.isBlank(appKey)) {
|
||||
appKey = authenticationConfig.getTokenDefaultAppKey();
|
||||
}
|
||||
return appKey;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user