mirror of
http://git.pig4cloud.com/pig/pigx.git
synced 2026-11-08 12:39:05 +08:00
✨ common-security 能力增强,支持手动传递token 到下游服务
(cherry picked from commit df53f305efa807972f836608cbaf577ee43bc071)
This commit is contained in:
1 parent
812684757c
commit
116d2d664c
3 files changed
+105
-30
No files matched your search
+36
-30
@@ -4,6 +4,7 @@ import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.pig4cloud.pigx.common.core.constant.SecurityConstants;
|
||||
import com.pig4cloud.pigx.common.core.util.WebUtils;
|
||||
import com.pig4cloud.pigx.common.security.util.NonWebTokenContextHolder;
|
||||
import feign.RequestInterceptor;
|
||||
import feign.RequestTemplate;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
@@ -13,11 +14,12 @@ import org.springframework.security.oauth2.core.OAuth2AccessToken;
|
||||
import org.springframework.security.oauth2.server.resource.web.BearerTokenResolver;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
/**
|
||||
* oauth2 feign token传递
|
||||
*
|
||||
* <p>
|
||||
* 重新 OAuth2FeignRequestInterceptor ,官方实现部分常见不适用
|
||||
*
|
||||
* @author lengleng
|
||||
@@ -27,37 +29,41 @@ import java.util.Collection;
|
||||
@RequiredArgsConstructor
|
||||
public class PigxOAuthRequestInterceptor implements RequestInterceptor {
|
||||
|
||||
private final BearerTokenResolver tokenResolver;
|
||||
private final BearerTokenResolver tokenResolver;
|
||||
|
||||
/**
|
||||
* Create a template with the header of provided name and extracted extract </br>
|
||||
*
|
||||
* 1. 如果使用 非web 请求,header 区别 </br>
|
||||
*
|
||||
* 2. 根据authentication 还原请求token
|
||||
* @param template
|
||||
*/
|
||||
@Override
|
||||
public void apply(RequestTemplate template) {
|
||||
Collection<String> fromHeader = template.headers().get(SecurityConstants.FROM);
|
||||
// 带from 请求直接跳过
|
||||
if (CollUtil.isNotEmpty(fromHeader) && fromHeader.contains(SecurityConstants.FROM_IN)) {
|
||||
return;
|
||||
}
|
||||
/**
|
||||
* Create a template with the header of provided name and extracted extract </br>
|
||||
* <p>
|
||||
* 1. 如果使用 非web 请求,header 区别 </br>
|
||||
* <p>
|
||||
* 2. 根据authentication 还原请求token
|
||||
*
|
||||
* @param template
|
||||
*/
|
||||
@Override
|
||||
public void apply(RequestTemplate template) {
|
||||
Collection<String> fromHeader = template.headers().get(SecurityConstants.FROM);
|
||||
// 带from 请求直接跳过
|
||||
if (CollUtil.isNotEmpty(fromHeader) && fromHeader.contains(SecurityConstants.FROM_IN)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// 非web 请求直接跳过
|
||||
if (WebUtils.getRequest() == null) {
|
||||
return;
|
||||
}
|
||||
HttpServletRequest request = WebUtils.getRequest();
|
||||
// 避免请求参数的 query token 无法传递
|
||||
String token = tokenResolver.resolve(request);
|
||||
if (StrUtil.isBlank(token)) {
|
||||
return;
|
||||
}
|
||||
template.header(HttpHeaders.AUTHORIZATION,
|
||||
String.format("%s %s", OAuth2AccessToken.TokenType.BEARER.getValue(), token));
|
||||
// 非web 请求直接跳过
|
||||
String token = "";
|
||||
if (WebUtils.getRequest() == null) {
|
||||
token = NonWebTokenContextHolder.getToken();
|
||||
} else {
|
||||
HttpServletRequest request = WebUtils.getRequest();
|
||||
// 避免请求参数的 query token 无法传递
|
||||
token = tokenResolver.resolve(request);
|
||||
}
|
||||
|
||||
}
|
||||
if (StrUtil.isBlank(token)) {
|
||||
return;
|
||||
}
|
||||
template.header(HttpHeaders.AUTHORIZATION,
|
||||
String.format("%s %s", OAuth2AccessToken.TokenType.BEARER.getValue(), token));
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
+56
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* Copyright (c) 2018-2025, lengleng All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the pig4cloud.com developer nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
* Author: lengleng (wangiegie@gmail.com)
|
||||
*/
|
||||
|
||||
package com.pig4cloud.pigx.common.security.util;
|
||||
|
||||
import com.alibaba.ttl.TransmittableThreadLocal;
|
||||
import lombok.experimental.UtilityClass;
|
||||
|
||||
/**
|
||||
* @author lengleng
|
||||
* @date 2024-04-23
|
||||
* <p>
|
||||
* 在非web 调用feign 传递之前手动set token
|
||||
*/
|
||||
@UtilityClass
|
||||
public class NonWebTokenContextHolder {
|
||||
|
||||
private final ThreadLocal<String> THREAD_LOCAL_VERSION = new TransmittableThreadLocal<>();
|
||||
|
||||
/**
|
||||
* TTL 设置token<br/>
|
||||
*
|
||||
* @param token token
|
||||
*/
|
||||
public void setToken(String token) {
|
||||
THREAD_LOCAL_VERSION.set(token);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取TTL中的token
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public String getToken() {
|
||||
return THREAD_LOCAL_VERSION.get();
|
||||
}
|
||||
|
||||
public void clear() {
|
||||
THREAD_LOCAL_VERSION.remove();
|
||||
}
|
||||
|
||||
}
|
||||
+13
@@ -24,6 +24,7 @@ import lombok.experimental.UtilityClass;
|
||||
import org.springframework.security.core.Authentication;
|
||||
import org.springframework.security.core.GrantedAuthority;
|
||||
import org.springframework.security.core.context.SecurityContextHolder;
|
||||
import org.springframework.security.oauth2.server.resource.authentication.BearerTokenAuthentication;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
@@ -44,6 +45,18 @@ public class SecurityUtils {
|
||||
return SecurityContextHolder.getContext().getAuthentication();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取Authentication Token
|
||||
* @return
|
||||
*/
|
||||
public String getToken(){
|
||||
Authentication authentication = SecurityUtils.getAuthentication();
|
||||
if (authentication instanceof BearerTokenAuthentication bearerTokenAuthentication) {
|
||||
return bearerTokenAuthentication.getToken().getTokenValue();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取用户
|
||||
* @param authentication
|
||||
|
||||
Reference in new issue
Block a user