diff --git a/auth/api/src/main/java/com/tencent/supersonic/auth/api/authentication/pojo/UserWithPassword.java b/auth/api/src/main/java/com/tencent/supersonic/auth/api/authentication/pojo/UserWithPassword.java index aa2d5d05c..2ebfd3d9a 100644 --- a/auth/api/src/main/java/com/tencent/supersonic/auth/api/authentication/pojo/UserWithPassword.java +++ b/auth/api/src/main/java/com/tencent/supersonic/auth/api/authentication/pojo/UserWithPassword.java @@ -3,6 +3,17 @@ package com.tencent.supersonic.auth.api.authentication.pojo; import com.tencent.supersonic.common.pojo.User; import lombok.AllArgsConstructor; import lombok.Data; +import org.apache.commons.lang3.StringUtils; + +import java.util.HashMap; +import java.util.Map; + +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_USER_DISPLAY_NAME; +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; @Data @AllArgsConstructor @@ -20,4 +31,16 @@ public class UserWithPassword extends User { String password, Integer isAdmin) { return new UserWithPassword(id, name, displayName, email, password, isAdmin); } + + public static Map convert(UserWithPassword user) { + Map 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 claims; + } } diff --git a/auth/authentication/src/main/java/com/tencent/supersonic/auth/authentication/adaptor/DefaultUserAdaptor.java b/auth/authentication/src/main/java/com/tencent/supersonic/auth/authentication/adaptor/DefaultUserAdaptor.java index 3e927a51f..b14c68a78 100644 --- a/auth/authentication/src/main/java/com/tencent/supersonic/auth/authentication/adaptor/DefaultUserAdaptor.java +++ b/auth/authentication/src/main/java/com/tencent/supersonic/auth/authentication/adaptor/DefaultUserAdaptor.java @@ -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"); diff --git a/auth/authentication/src/main/java/com/tencent/supersonic/auth/authentication/interceptor/AuthenticationInterceptor.java b/auth/authentication/src/main/java/com/tencent/supersonic/auth/authentication/interceptor/AuthenticationInterceptor.java index e931d853d..3bf482ac7 100644 --- a/auth/authentication/src/main/java/com/tencent/supersonic/auth/authentication/interceptor/AuthenticationInterceptor.java +++ b/auth/authentication/src/main/java/com/tencent/supersonic/auth/authentication/interceptor/AuthenticationInterceptor.java @@ -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; diff --git a/auth/authentication/src/main/java/com/tencent/supersonic/auth/authentication/interceptor/DefaultAuthenticationInterceptor.java b/auth/authentication/src/main/java/com/tencent/supersonic/auth/authentication/interceptor/DefaultAuthenticationInterceptor.java index 97f094c6e..adcd64ed7 100644 --- a/auth/authentication/src/main/java/com/tencent/supersonic/auth/authentication/interceptor/DefaultAuthenticationInterceptor.java +++ b/auth/authentication/src/main/java/com/tencent/supersonic/auth/authentication/interceptor/DefaultAuthenticationInterceptor.java @@ -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 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); + } } diff --git a/auth/authentication/src/main/java/com/tencent/supersonic/auth/authentication/strategy/HttpHeaderUserStrategy.java b/auth/authentication/src/main/java/com/tencent/supersonic/auth/authentication/strategy/HttpHeaderUserStrategy.java index 799245a91..446143db6 100644 --- a/auth/authentication/src/main/java/com/tencent/supersonic/auth/authentication/strategy/HttpHeaderUserStrategy.java +++ b/auth/authentication/src/main/java/com/tencent/supersonic/auth/authentication/strategy/HttpHeaderUserStrategy.java @@ -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 claimsOptional = tokenService.getClaims(request); + return claimsOptional.map(this::getUser).orElse(User.getVisitUser()); + } + + public User getUser(String token, String appKey) { + final Optional 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); + } + } diff --git a/auth/authentication/src/main/java/com/tencent/supersonic/auth/authentication/utils/TokenService.java b/auth/authentication/src/main/java/com/tencent/supersonic/auth/authentication/utils/TokenService.java new file mode 100644 index 000000000..7e01b3357 --- /dev/null +++ b/auth/authentication/src/main/java/com/tencent/supersonic/auth/authentication/utils/TokenService.java @@ -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 claims, HttpServletRequest request) { + String appKey = getAppKey(request); + return generateToken(claims, appKey); + } + + public String generateToken(Map claims, String appKey) { + return toTokenString(claims, appKey); + } + + private String toTokenString(Map 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 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 getClaims(HttpServletRequest request) { + String token = request.getHeader(authenticationConfig.getTokenHttpHeaderKey()); + String appKey = getAppKey(request); + return getClaims(token, appKey); + } + + public Optional 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; + } +} diff --git a/auth/authentication/src/main/java/com/tencent/supersonic/auth/authentication/utils/UserTokenUtils.java b/auth/authentication/src/main/java/com/tencent/supersonic/auth/authentication/utils/UserTokenUtils.java deleted file mode 100644 index 20fba71f6..000000000 --- a/auth/authentication/src/main/java/com/tencent/supersonic/auth/authentication/utils/UserTokenUtils.java +++ /dev/null @@ -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 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 claimsOptional = getClaims(token, request); - return claimsOptional.map(this::getUser).orElse(User.getVisitUser()); - } - - public User getUser(String token, String appKey) { - final Optional 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 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 getClaims(String token, HttpServletRequest request) { - String appKey = getAppKey(request); - return getClaims(token, appKey); - } - - private Optional 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 claims, String appKey) { - return toTokenString(claims, appKey); - } - - private String toTokenString(Map 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 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; - } -}