From 116d2d664c4b667c32ec3136f0a6ba40c92eed99 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=86=B7=E5=86=B7?= <2270033969@qq.com> Date: Wed, 24 Apr 2024 16:15:27 +0800 Subject: [PATCH] =?UTF-8?q?=E2=9C=A8=20common-security=20=E8=83=BD?= =?UTF-8?q?=E5=8A=9B=E5=A2=9E=E5=BC=BA=EF=BC=8C=E6=94=AF=E6=8C=81=E6=89=8B?= =?UTF-8?q?=E5=8A=A8=E4=BC=A0=E9=80=92token=20=E5=88=B0=E4=B8=8B=E6=B8=B8?= =?UTF-8?q?=E6=9C=8D=E5=8A=A1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit (cherry picked from commit df53f305efa807972f836608cbaf577ee43bc071) --- .../feign/PigxOAuthRequestInterceptor.java | 66 ++++++++++--------- .../util/NonWebTokenContextHolder.java | 56 ++++++++++++++++ .../common/security/util/SecurityUtils.java | 13 ++++ 3 files changed, 105 insertions(+), 30 deletions(-) create mode 100644 pigx-common/pigx-common-security/src/main/java/com/pig4cloud/pigx/common/security/util/NonWebTokenContextHolder.java diff --git a/pigx-common/pigx-common-security/src/main/java/com/pig4cloud/pigx/common/security/feign/PigxOAuthRequestInterceptor.java b/pigx-common/pigx-common-security/src/main/java/com/pig4cloud/pigx/common/security/feign/PigxOAuthRequestInterceptor.java index 8177d17ec..a2712cce4 100644 --- a/pigx-common/pigx-common-security/src/main/java/com/pig4cloud/pigx/common/security/feign/PigxOAuthRequestInterceptor.java +++ b/pigx-common/pigx-common-security/src/main/java/com/pig4cloud/pigx/common/security/feign/PigxOAuthRequestInterceptor.java @@ -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传递 - * + *

* 重新 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
- * - * 1. 如果使用 非web 请求,header 区别
- * - * 2. 根据authentication 还原请求token - * @param template - */ - @Override - public void apply(RequestTemplate template) { - Collection 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
+ *

+ * 1. 如果使用 非web 请求,header 区别
+ *

+ * 2. 根据authentication 还原请求token + * + * @param template + */ + @Override + public void apply(RequestTemplate template) { + Collection 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)); + + } } diff --git a/pigx-common/pigx-common-security/src/main/java/com/pig4cloud/pigx/common/security/util/NonWebTokenContextHolder.java b/pigx-common/pigx-common-security/src/main/java/com/pig4cloud/pigx/common/security/util/NonWebTokenContextHolder.java new file mode 100644 index 000000000..5654f46d3 --- /dev/null +++ b/pigx-common/pigx-common-security/src/main/java/com/pig4cloud/pigx/common/security/util/NonWebTokenContextHolder.java @@ -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 + *

+ * 在非web 调用feign 传递之前手动set token + */ +@UtilityClass +public class NonWebTokenContextHolder { + + private final ThreadLocal THREAD_LOCAL_VERSION = new TransmittableThreadLocal<>(); + + /** + * TTL 设置token
+ * + * @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(); + } + +} diff --git a/pigx-common/pigx-common-security/src/main/java/com/pig4cloud/pigx/common/security/util/SecurityUtils.java b/pigx-common/pigx-common-security/src/main/java/com/pig4cloud/pigx/common/security/util/SecurityUtils.java index b06ae66b3..338e2435d 100644 --- a/pigx-common/pigx-common-security/src/main/java/com/pig4cloud/pigx/common/security/util/SecurityUtils.java +++ b/pigx-common/pigx-common-security/src/main/java/com/pig4cloud/pigx/common/security/util/SecurityUtils.java @@ -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