定义ContextHolder
/**
* 获取当前线程变量中的 用户id、用户名称、Token等信息
* 注意: 必须在网关通过请求头的方法传入,同时在Interceptor拦截器设置值。 否则这里无法获取
*
*
*/
public class SecurityContextHolder
{
private static final TransmittableThreadLocal<Map<String, Object>> THREAD_LOCAL = new TransmittableThreadLocal<>();
public static void set(String key, Object value)
{
Map<String, Object> map = getLocalMap();
map.put(key, value == null ? StringUtils.EMPTY : value);
}
public static String get(String key)
{
Map<String, Object> map = getLocalMap();
return Convert.toStr(map.getOrDefault(key, StringUtils.EMPTY));
}
public static <T> T get(String key, Class<T> clazz)
{
Map<String, Object> map = getLocalMap();
return StringUtils.cast(map.getOrDefault(key, null));
}
public static Map<String, Object> getLocalMap()
{
Map<String, Object> map = THREAD_LOCAL.get();
if (map == null)
{
map = new ConcurrentHashMap<String, Object>();
THREAD_LOCAL.set(map);
}
return map;
}
public static void setLocalMap(Map<String, Object> threadLocalMap)
{
THREAD_LOCAL.set(threadLocalMap);
}
public static String getUserId()
{
return get(SecurityConstants.DETAILS_USER_ID);
}
public static void setUserId(String account)
{
set(SecurityConstants.DETAILS_USER_ID, account);
}
public static String getUserName()
{
return get(SecurityConstants.DETAILS_USERNAME);
}
public static void setUserName(String username)
{
set(SecurityConstants.DETAILS_USERNAME, username);
}
public static String getUserKey()
{
return get(SecurityConstants.USER_KEY);
}
public static void setUserKey(String userKey)
{
set(SecurityConstants.USER_KEY, userKey);
}
public static void remove()
{
THREAD_LOCAL.remove();
}
public static void setUserType(String userType) {
set(SecurityConstants.USER_TYPE, userType);
}
public static String getUserType()
{
return get(SecurityConstants.USER_TYPE);
}
}
应用模块的拦截器存放登录信息
@Component
public class SjcjInterceptor implements HandlerInterceptor {
@Autowired
private RemoteUserService remoteUserService;
@Autowired
private TokenService tokenService;
//超管的id=1
@Value("${admin.userId:1}")
private String adminUserId;
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
if (!(handler instanceof HandlerMethod)) {
return true;
}
String userId = SecurityContextHolder.getUserId();
if(StringUtils.isEmpty(userId)){
userId = adminUserId;
R<LoginUser> userResult = remoteUserService.getUserIdInfo(userId, SecurityConstants.INNER);
if (R.FAIL == userResult.getCode())
{
throw new ServiceException(userResult.getMsg());
}
LoginUser userInfo = userResult.getData();
Map<String, Object> rspMap = tokenService.createToken(userInfo, 1);
SecurityContextHolder.setUserId(userInfo.getUserid());
SecurityContextHolder.setUserName(userInfo.getUsername());
SecurityContextHolder.set(SecurityConstants.LOGIN_USER, userInfo);
SecurityContextHolder.set(SecurityConstants.AUTHORIZATION_HEADER,rspMap.get("access_token"));
}
return true;
}
}
feign 请求拦截器
/**
* feign 请求拦截器
*
*
*/
@Component
public class FeignRequestInterceptor implements RequestInterceptor
{
@Override
public void apply(RequestTemplate requestTemplate)
{
HttpServletRequest httpServletRequest = ServletUtils.getRequest();
if (StringUtils.isNotNull(httpServletRequest))
{
Map<String, String> headers = ServletUtils.getHeaders(httpServletRequest);
// 传递用户信息请求头,防止丢失
String userId = headers.get(SecurityConstants.DETAILS_USER_ID);
//cjq 2022/10/12
//从request没取到,则从SecurityContextHolder从取
//适应于无前端的情况,在接口调用前,把用户信息放到SecurityContextHolder
if(StringUtils.isEmpty(userId)){
userId = SecurityContextHolder.get(SecurityConstants.DETAILS_USER_ID);
}
if (StringUtils.isNotEmpty(userId))
{
requestTemplate.header(SecurityConstants.DETAILS_USER_ID, userId);
}
String userName = headers.get(SecurityConstants.DETAILS_USERNAME);
if (StringUtils.isEmpty(userName)){
userName = SecurityContextHolder.get(SecurityConstants.DETAILS_USERNAME);
}
if (StringUtils.isNotEmpty(userName))
{
requestTemplate.header(SecurityConstants.DETAILS_USERNAME, userName);
}
String authentication = headers.get(SecurityConstants.AUTHORIZATION_HEADER);
if (StringUtils.isNotEmpty(authentication)){
authentication = SecurityContextHolder.get(SecurityConstants.AUTHORIZATION_HEADER);
}
if (StringUtils.isNotEmpty(authentication))
{
requestTemplate.header(SecurityConstants.AUTHORIZATION_HEADER, authentication);
}
// 配置客户端IP
requestTemplate.header("X-Forwarded-For", IpUtils.getIpAddr(ServletUtils.getRequest()));
}
}
}
可以使用SecurityContextHolder获取相关的信息了。