token 传递优化,提高性能

This commit is contained in:
冷冷 2018-04-10 23:51:57 +08:00
parent caa1cf3aac
commit 41b450558d
6 changed files with 36 additions and 50 deletions
pig-auth/src/main/java/com/github/pig/auth/config
pig-common/src/main/java/com/github/pig/common
pig-gateway/src/main/java/com/github/pig/gateway/componet

View File

@ -12,14 +12,11 @@ import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.oauth2.common.DefaultOAuth2AccessToken;
import org.springframework.security.oauth2.common.OAuth2AccessToken;
import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableAuthorizationServer;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerSecurityConfigurer;
import org.springframework.security.oauth2.provider.OAuth2Authentication;
import org.springframework.security.oauth2.provider.token.AccessTokenConverter;
import org.springframework.security.oauth2.provider.token.TokenEnhancer;
import org.springframework.security.oauth2.provider.token.TokenEnhancerChain;
import org.springframework.security.oauth2.provider.token.TokenStore;
@ -93,7 +90,7 @@ public class PigAuthorizationConfig extends AuthorizationServerConfigurerAdapter
@Bean
public JwtAccessTokenConverter jwtAccessTokenConverter() {
JwtAccessTokenConverter jwtAccessTokenConverter = new PigJwtAccessTokenConverter();
PigJwtAccessTokenConverter jwtAccessTokenConverter = new PigJwtAccessTokenConverter();
jwtAccessTokenConverter.setSigningKey(CommonConstant.SIGN_KEY);
return jwtAccessTokenConverter;
}

View File

@ -1,8 +1,6 @@
package com.github.pig.common.bean.config;
import com.github.pig.common.bean.resolver.TokenArgumentResolver;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.CacheManager;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
@ -16,11 +14,8 @@ import java.util.List;
*/
@Configuration
public class WebMvcConfig extends WebMvcConfigurerAdapter {
@Autowired
private CacheManager cacheManager;
@Override
public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {
argumentResolvers.add(new TokenArgumentResolver(cacheManager));
argumentResolvers.add(new TokenArgumentResolver());
}
}

View File

@ -1,13 +1,10 @@
package com.github.pig.common.bean.resolver;
import com.github.pig.common.constant.SecurityConstants;
import com.github.pig.common.util.UserUtils;
import com.github.pig.common.vo.SysRole;
import com.github.pig.common.vo.UserVO;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.cache.CacheManager;
import com.xiaoleilu.hutool.util.StrUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.MethodParameter;
import org.springframework.web.bind.support.WebDataBinderFactory;
@ -17,22 +14,17 @@ import org.springframework.web.method.support.ModelAndViewContainer;
import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Optional;
/**
* @author lengleng
* @date 2017/12/21
* Token转化UserVo
*/
@Slf4j
@Configuration
public class TokenArgumentResolver implements HandlerMethodArgumentResolver {
private Logger logger = LoggerFactory.getLogger(getClass());
private CacheManager cacheManager;
public TokenArgumentResolver(CacheManager cacheManager) {
this.cacheManager = cacheManager;
}
/**
* 1. 入参筛选
@ -46,10 +38,6 @@ public class TokenArgumentResolver implements HandlerMethodArgumentResolver {
}
/**
* 1. 先从 cache 中判断token 是否已经有缓存
* 2. 不存在缓存情况解析token 获取用户信息
* 3. 不存在缓存情况在AOP进行缓存添加因为这里添加只会对入参含有 UserVo的生效而不是全局
*
* @param methodParameter 入参集合
* @param modelAndViewContainer model view
* @param nativeWebRequest web相关
@ -61,37 +49,24 @@ public class TokenArgumentResolver implements HandlerMethodArgumentResolver {
public Object resolveArgument(MethodParameter methodParameter,
ModelAndViewContainer modelAndViewContainer,
NativeWebRequest nativeWebRequest,
WebDataBinderFactory webDataBinderFactory) throws Exception {
WebDataBinderFactory webDataBinderFactory) {
HttpServletRequest request = nativeWebRequest.getNativeRequest(HttpServletRequest.class);
String token = UserUtils.getToken(request);
if (StringUtils.isBlank(token)) {
logger.error("resolveArgument error token is empty");
String username = request.getHeader(SecurityConstants.USER_HEADER);
String roles = request.getHeader(SecurityConstants.ROLE_HEADER);
if (StrUtil.isBlank(username) || StrUtil.isBlank(roles)) {
log.warn("resolveArgument error username or role is empty");
return null;
}
Optional<UserVO> optional = Optional.ofNullable(cacheManager.getCache(SecurityConstants.TOKEN_USER_DETAIL).get(token, UserVO.class));
if (optional.isPresent()) {
logger.info("return cache user vo,token :{}", token);
return optional.get();
}
return optional.orElseGet(() -> generatorByToken(request, token));
}
private UserVO generatorByToken(HttpServletRequest request, String token) {
String username = UserUtils.getUserName(request);
List<String> roles = UserUtils.getRole(request);
logger.info("Auth-Token-User:{}-Roles:{}", username, roles);
UserVO userVo = new UserVO();
userVo.setUsername(username);
UserVO userVO = new UserVO();
userVO.setUsername(username);
List<SysRole> sysRoleList = new ArrayList<>();
roles.stream().forEach(role -> {
Arrays.stream(roles.split(",")).forEach(role -> {
SysRole sysRole = new SysRole();
sysRole.setRoleName(role);
sysRoleList.add(sysRole);
});
userVo.setRoleList(sysRoleList);
cacheManager.getCache(SecurityConstants.TOKEN_USER_DETAIL).put(token, userVo);
return userVo;
userVO.setRoleList(sysRoleList);
return userVO;
}
}

View File

@ -9,6 +9,15 @@ public interface SecurityConstants {
* 前缀
*/
String PIG_PREFIX = "pig_";
/**
* 用户信息头
*/
String USER_HEADER = "x-user-header";
/**
* 角色信息头
*/
String ROLE_HEADER = "x-role-header";
/**
* 项目的license
*/

View File

@ -16,7 +16,6 @@ import org.springframework.security.oauth2.config.annotation.web.configuration.R
import org.springframework.security.oauth2.config.annotation.web.configurers.ResourceServerSecurityConfigurer;
import org.springframework.security.oauth2.provider.expression.OAuth2WebSecurityExpressionHandler;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
/**
* @author lengleng
* @date 2017/10/27

View File

@ -1,8 +1,12 @@
package com.github.pig.gateway.componet.filter;
import com.github.pig.common.constant.SecurityConstants;
import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import com.xiaoleilu.hutool.collection.CollectionUtil;
import org.springframework.cloud.netflix.zuul.filters.support.FilterConstants;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Component;
import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.FORM_BODY_WRAPPER_FILTER_ORDER;
@ -34,6 +38,13 @@ public class AccessFilter extends ZuulFilter {
public Object run() {
RequestContext ctx = RequestContext.getCurrentContext();
ctx.set("startTime", System.currentTimeMillis());
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
if (authentication != null) {
RequestContext requestContext = RequestContext.getCurrentContext();
requestContext.addZuulRequestHeader(SecurityConstants.USER_HEADER, authentication.getName());
requestContext.addZuulRequestHeader(SecurityConstants.ROLE_HEADER, CollectionUtil.join(authentication.getAuthorities(),","));
}
return null;
}
}