diff --git a/axzo-auth-spring-boot-starter/src/main/java/cn/axzo/framework/auth/annotation/PreBuildContext.java b/axzo-auth-spring-boot-starter/src/main/java/cn/axzo/framework/auth/annotation/PreBuildContext.java new file mode 100644 index 0000000..f3b535f --- /dev/null +++ b/axzo-auth-spring-boot-starter/src/main/java/cn/axzo/framework/auth/annotation/PreBuildContext.java @@ -0,0 +1,14 @@ +package cn.axzo.framework.auth.annotation; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Target({ElementType.METHOD, ElementType.TYPE}) +@Retention(RetentionPolicy.RUNTIME) +@Documented +public @interface PreBuildContext { + String value() default ""; +} diff --git a/axzo-auth-spring-boot-starter/src/main/java/cn/axzo/framework/auth/annotation/PreBuildUser.java b/axzo-auth-spring-boot-starter/src/main/java/cn/axzo/framework/auth/annotation/PreBuildUser.java deleted file mode 100644 index d313ce6..0000000 --- a/axzo-auth-spring-boot-starter/src/main/java/cn/axzo/framework/auth/annotation/PreBuildUser.java +++ /dev/null @@ -1,17 +0,0 @@ -package cn.axzo.framework.auth.annotation; - -import cn.axzo.framework.auth.domain.RequestInfo; - -import java.lang.annotation.*; - -@Target({ElementType.METHOD, ElementType.TYPE}) -@Retention(RetentionPolicy.RUNTIME) -@Documented -public @interface PreBuildUser { - String value() default ""; - - /** - * RequestInfo子类Class对象 - */ - Class requestInfo() default RequestInfo.class; -} diff --git a/axzo-auth-spring-boot-starter/src/main/java/cn/axzo/framework/auth/config/ContextInfoConfiguration.java b/axzo-auth-spring-boot-starter/src/main/java/cn/axzo/framework/auth/config/ContextInfoConfiguration.java new file mode 100644 index 0000000..1011dd4 --- /dev/null +++ b/axzo-auth-spring-boot-starter/src/main/java/cn/axzo/framework/auth/config/ContextInfoConfiguration.java @@ -0,0 +1,14 @@ +package cn.axzo.framework.auth.config; + +import cn.axzo.framework.auth.service.ContextInfoBuilderAspect; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +@Configuration +public class ContextInfoConfiguration { + + @Bean + public ContextInfoBuilderAspect ContextInfoBuilderAspect() { + return new ContextInfoBuilderAspect(); + } +} diff --git a/axzo-auth-spring-boot-starter/src/main/java/cn/axzo/framework/auth/config/UserInfoConfiguration.java b/axzo-auth-spring-boot-starter/src/main/java/cn/axzo/framework/auth/config/UserInfoConfiguration.java deleted file mode 100644 index edc5240..0000000 --- a/axzo-auth-spring-boot-starter/src/main/java/cn/axzo/framework/auth/config/UserInfoConfiguration.java +++ /dev/null @@ -1,13 +0,0 @@ -package cn.axzo.framework.auth.config; -import cn.axzo.framework.auth.service.BuilderUserInfoAspect; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; - -@Configuration -public class UserInfoConfiguration { - - @Bean - public BuilderUserInfoAspect builderUserInfoAspect(){ - return new BuilderUserInfoAspect(); - } -} diff --git a/axzo-auth-spring-boot-starter/src/main/java/cn/axzo/framework/auth/constants/AopConstants.java b/axzo-auth-spring-boot-starter/src/main/java/cn/axzo/framework/auth/constants/AopConstants.java index 51a9478..ed9c541 100644 --- a/axzo-auth-spring-boot-starter/src/main/java/cn/axzo/framework/auth/constants/AopConstants.java +++ b/axzo-auth-spring-boot-starter/src/main/java/cn/axzo/framework/auth/constants/AopConstants.java @@ -3,11 +3,14 @@ package cn.axzo.framework.auth.constants; public class AopConstants { private AopConstants(){} public static final String HEADER_TENANT = "tenantId"; - public static final String HEADER_SYSTEM_TYPE = "1"; - public static final String HEADER_AUTH = "authorization"; + + public static final String HEADER_SYSTEM_TYPE = "systemType"; + public static final String HEADER_SYSTEM_VERSION = "systemVersion"; + public static final String HEADER_DEVICE_KIND = "deviceKind"; public static final String HEADER_DEVICE_NO = "deviceNo"; public static final String HEADER_APP_VERSION = "appVersion"; + public static final String HEADER_SAAS_TENANT_ID = "SAAS_TENANT_ID"; public static final String HEADER_WORKSPACE_ID = "workspaceId"; public static final String VISIT_TO = "visitTo"; @@ -15,6 +18,7 @@ public class AopConstants { public static final String ENV_DEV="dev"; + public static final String HEADER_AUTH = "authorization"; diff --git a/axzo-auth-spring-boot-starter/src/main/java/cn/axzo/framework/auth/domain/ContextInfo.java b/axzo-auth-spring-boot-starter/src/main/java/cn/axzo/framework/auth/domain/ContextInfo.java new file mode 100644 index 0000000..9d3faba --- /dev/null +++ b/axzo-auth-spring-boot-starter/src/main/java/cn/axzo/framework/auth/domain/ContextInfo.java @@ -0,0 +1,57 @@ +package cn.axzo.framework.auth.domain; + +import javax.servlet.http.HttpServletRequest; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; +import lombok.extern.slf4j.Slf4j; + +@Data +@Slf4j +@AllArgsConstructor +@NoArgsConstructor +public class ContextInfo { + + private String token; + + private UserInfo userInfo; + + private SystemAndDeviceInfo systemAndDeviceInfo; + + private TerminalInfo terminalInfo; + + /** + * 项目空间id + */ + private Long workspaceId; + + /** + * 单位id + */ + private String ouId; + + /** + * 租户id + */ + private String tenantId; + + /** + * saas租户id + */ + private Long saasTenantId; + + private String visitTo; + + + public void buildCustomUserInfo(UserInfoMap userInfoMap){ + /** + * {@link cn.axzo.apollo.server.common.config.auth.UserContextFilter.PARAMETER_PROJECTID} + */ + } + + + public void buildCustomInfo(HttpServletRequest request) { + } + +} diff --git a/axzo-auth-spring-boot-starter/src/main/java/cn/axzo/framework/auth/domain/ContextInfoHolder.java b/axzo-auth-spring-boot-starter/src/main/java/cn/axzo/framework/auth/domain/ContextInfoHolder.java new file mode 100644 index 0000000..24de5af --- /dev/null +++ b/axzo-auth-spring-boot-starter/src/main/java/cn/axzo/framework/auth/domain/ContextInfoHolder.java @@ -0,0 +1,27 @@ +package cn.axzo.framework.auth.domain; + +import com.alibaba.ttl.TransmittableThreadLocal; + +/** + * 用户信息上下文 holder + * @author zhangtianyu + * @date 2022/5/11 11:21 AM + **/ +public class ContextInfoHolder { + private static final TransmittableThreadLocal CONTEXT = new TransmittableThreadLocal<>(); + + private ContextInfoHolder(){} + + public static void set(ContextInfo contextInfo) { + CONTEXT.set(contextInfo); + } + + public static ContextInfo get() { + return CONTEXT.get(); + } + + public static void clear() { + CONTEXT.remove(); + } + +} diff --git a/axzo-auth-spring-boot-starter/src/main/java/cn/axzo/framework/auth/domain/RequestInfo.java b/axzo-auth-spring-boot-starter/src/main/java/cn/axzo/framework/auth/domain/RequestInfo.java deleted file mode 100644 index 7ebc137..0000000 --- a/axzo-auth-spring-boot-starter/src/main/java/cn/axzo/framework/auth/domain/RequestInfo.java +++ /dev/null @@ -1,37 +0,0 @@ -package cn.axzo.framework.auth.domain; - -import lombok.Data; - -import javax.servlet.http.HttpServletRequest; - -/** - * 请求数据 - * @author zhangtianyu - * @date 2022/4/25 10:10 AM - **/ -@Data -public class RequestInfo { - /** - * 租户id - */ - private String tenantId; - /** - * saas租户id - */ - private Long saasTenantId; - private String systemType; - private String deviceKind; - private String deviceNo; - private String appVersion; - private String token; - private String visitTo; - /** - * 项目空间id - */ - private Long workspaceId; - /** - * 使用http request 设置自定义字段 - * @param request http请求 - */ - public void buildCustomRequestInfo(HttpServletRequest request) {} -} diff --git a/axzo-auth-spring-boot-starter/src/main/java/cn/axzo/framework/auth/domain/SystemAndDeviceInfo.java b/axzo-auth-spring-boot-starter/src/main/java/cn/axzo/framework/auth/domain/SystemAndDeviceInfo.java new file mode 100644 index 0000000..6019a00 --- /dev/null +++ b/axzo-auth-spring-boot-starter/src/main/java/cn/axzo/framework/auth/domain/SystemAndDeviceInfo.java @@ -0,0 +1,16 @@ +package cn.axzo.framework.auth.domain; + +import lombok.Data; + +import javax.servlet.http.HttpServletRequest; + +/** + **/ +@Data +public class SystemAndDeviceInfo { + + private String systemType; + private String deviceKind; + private String deviceNo; + private String appVersion; +} diff --git a/axzo-auth-spring-boot-starter/src/main/java/cn/axzo/framework/auth/domain/TerminalInfo.java b/axzo-auth-spring-boot-starter/src/main/java/cn/axzo/framework/auth/domain/TerminalInfo.java new file mode 100644 index 0000000..57b145a --- /dev/null +++ b/axzo-auth-spring-boot-starter/src/main/java/cn/axzo/framework/auth/domain/TerminalInfo.java @@ -0,0 +1,16 @@ +package cn.axzo.framework.auth.domain; + +public class TerminalInfo { + + + private String terminal; + + CMS = NT_CMS, (1, cms) + + + boolean isCMS() { + if("1".equals(terminal)) { + + } + } +} diff --git a/axzo-auth-spring-boot-starter/src/main/java/cn/axzo/framework/auth/domain/UserInfo.java b/axzo-auth-spring-boot-starter/src/main/java/cn/axzo/framework/auth/domain/UserInfo.java index c882a77..dfb5272 100644 --- a/axzo-auth-spring-boot-starter/src/main/java/cn/axzo/framework/auth/domain/UserInfo.java +++ b/axzo-auth-spring-boot-starter/src/main/java/cn/axzo/framework/auth/domain/UserInfo.java @@ -7,83 +7,71 @@ import lombok.extern.slf4j.Slf4j; import java.util.List; - @Data @Slf4j @AllArgsConstructor @NoArgsConstructor public class UserInfo { - /** - * 客户端Id - */ - private String clientId; - /** - * 身份证 - */ - private String idCard; - /** - * 身份验证过期时间 - */ - private boolean credentialsNonExpired; - /** - * 角色 - */ - private List roles; - /** - * 性别 - */ - private int sex; - /** - * 终端 - */ - private String terminal; - /** - * axzoId - */ - private Long userId; - /** - * 权限列表 - */ - private List authorities; - /** - * 是否有效 - */ - private boolean enabled; - /** - * 账户是否被锁定 - */ - private boolean isLock; - /** - * 真实姓名 - */ - private String realName; - /** - * 密码 - */ - private String password; - /** - * 手机号 - */ - private String phoneNumber; - /** - * id - */ - private Long id; - private boolean accountNonLocked; - private String username; + + /** + * 客户端Id + */ + private String clientId; + /** + * 身份证 + */ + private String idCard; + /** + * 身份验证过期时间 + */ + private boolean credentialsNonExpired; + /** + * 角色 + */ + private List roles; + /** + * 性别 + */ + private int sex; + /** + * 终端 + */ + private String terminal; + /** + * axzoId + */ + private Long userId; + /** + * 权限列表 + */ + private List authorities; + /** + * 是否有效 + */ + private boolean enabled; + /** + * 账户是否被锁定 + */ + private boolean isLock; + /** + * 真实姓名 + */ + private String realName; + /** + * 密码 + */ + private String password; + /** + * 手机号 + */ + private String phoneNumber; + /** + * id + */ + private Long id; + + private boolean accountNonLocked; + + private String username; - /** - * 请求信息 - */ - private RequestInfo requestInfo; - - /** - * 使用用户信息map 设置自定义字段 - * @param userInfoMap 用户信息 - */ - public void buildCustomUserInfo(UserInfoMap userInfoMap){} - - public T getRequestInfo() { - return (T) requestInfo; - } } diff --git a/axzo-auth-spring-boot-starter/src/main/java/cn/axzo/framework/auth/domain/UserInfoHolder.java b/axzo-auth-spring-boot-starter/src/main/java/cn/axzo/framework/auth/domain/UserInfoHolder.java deleted file mode 100644 index daf1890..0000000 --- a/axzo-auth-spring-boot-starter/src/main/java/cn/axzo/framework/auth/domain/UserInfoHolder.java +++ /dev/null @@ -1,27 +0,0 @@ -package cn.axzo.framework.auth.domain; - -import com.alibaba.ttl.TransmittableThreadLocal; - -/** - * 用户信息上下文 holder - * @author zhangtianyu - * @date 2022/5/11 11:21 AM - **/ -public class UserInfoHolder { - private static final TransmittableThreadLocal CONTEXT = new TransmittableThreadLocal<>(); - - private UserInfoHolder(){} - - public static void set(UserInfo userInfo) { - CONTEXT.set(userInfo); - } - - public static UserInfo get() { - return CONTEXT.get(); - } - - public static void clear() { - CONTEXT.remove(); - } - -} diff --git a/axzo-auth-spring-boot-starter/src/main/java/cn/axzo/framework/auth/service/BuilderUserInfoAspect.java b/axzo-auth-spring-boot-starter/src/main/java/cn/axzo/framework/auth/service/BuilderUserInfoAspect.java deleted file mode 100644 index 19f6b66..0000000 --- a/axzo-auth-spring-boot-starter/src/main/java/cn/axzo/framework/auth/service/BuilderUserInfoAspect.java +++ /dev/null @@ -1,173 +0,0 @@ -package cn.axzo.framework.auth.service; - -import cn.axzo.framework.auth.AuthException; -import cn.axzo.framework.auth.annotation.PreBuildUser; -import cn.axzo.framework.auth.constants.AopConstants; -import cn.axzo.framework.auth.domain.RequestInfo; -import cn.axzo.framework.auth.domain.UserInfo; -import cn.axzo.framework.auth.domain.UserInfoHolder; -import cn.axzo.framework.auth.enums.EnvEnum; -import cn.azxo.framework.common.logger.logback.PodNamespacePropertyDefiner; -import cn.hutool.core.bean.BeanUtil; -import cn.hutool.core.codec.Base64; -import cn.hutool.core.text.CharSequenceUtil; -import cn.hutool.http.HttpException; -import cn.hutool.http.HttpRequest; -import cn.axzo.framework.auth.domain.UserInfoMap; -import cn.hutool.core.lang.TypeReference; -import cn.hutool.json.JSONUtil; -import lombok.SneakyThrows; -import lombok.extern.slf4j.Slf4j; -import org.aspectj.lang.ProceedingJoinPoint; -import org.aspectj.lang.annotation.Around; -import org.aspectj.lang.annotation.Aspect; -import org.aspectj.lang.reflect.MethodSignature; -import org.springframework.core.annotation.Order; -import org.springframework.stereotype.Component; -import org.springframework.web.context.request.RequestContextHolder; -import org.springframework.web.context.request.ServletRequestAttributes; - -import javax.servlet.http.HttpServletRequest; -import java.lang.reflect.Method; -import java.util.Map; -import java.util.Objects; - - -@Slf4j -@Aspect -@Component -@Order(1) -public class BuilderUserInfoAspect { - - @Around(value = "@within(preBuildUser)") - public Object classHandler(ProceedingJoinPoint pjp, PreBuildUser preBuildUser) { - return handle(pjp, preBuildUser); - } - - @Around(value = "@annotation(preBuildUser)") - public Object methodHandler(ProceedingJoinPoint pjp, PreBuildUser preBuildUser) { - return handle(pjp, preBuildUser); - } - - @SneakyThrows - public Object handle(ProceedingJoinPoint pjp, PreBuildUser preBuildUser) { - HttpServletRequest httpRequest = null; - try { - //获取request - httpRequest = ((ServletRequestAttributes) Objects.requireNonNull(RequestContextHolder.getRequestAttributes())).getRequest(); - } catch (Exception exception) { - log.error("can not get request,there is a error occurrence ==>" + exception.getCause().getMessage()); - } - AuthException.error(Objects.nonNull(httpRequest), "httpRequest cant be null, this is error"); - - fillInUserInfoDetail(httpRequest, pjp, preBuildUser.requestInfo()); - try { - return pjp.proceed(); - } finally { - UserInfoHolder.clear(); - } - } - - public void fillInUserInfoDetail(HttpServletRequest request, ProceedingJoinPoint pjp, Class requestInfoClass) { - String userinfoJson; - // 本地运行 分两种情况 postMan/junit - // 判断本地环境 - if (getSystemProperties() == null) { - // 如果本地环境 有两种如果是postman类型调用手动调用pudge - String token = request.getHeader("Authorization"); - if (CharSequenceUtil.isEmpty(token)) { - // 硬逻辑 如果不携带token 可理解为junit测试 这里不覆盖 Userinfo的信息 - return; - } - userinfoJson = getUserInfoFromToken(token); - } else { - // 走 apisix 获取的请求 - String userJsonInfo = request.getHeader(AopConstants.USER_INFO); - AuthException.error(CharSequenceUtil.isNotEmpty(userJsonInfo), "do not have userinfo error , please check apisix config is correct"); - // 转编码 - userinfoJson = Base64.decodeStr(userJsonInfo); - - } - - MethodSignature methodSignature = (MethodSignature) pjp.getSignature(); - Method method = methodSignature.getMethod(); - Class[] parameterTypes = method.getParameterTypes(); - Object[] pjpArgs = pjp.getArgs(); - UserInfo userInfo = new UserInfo(); - for (int i = 0; i < parameterTypes.length; i++) { - if (parameterTypes[i].isAssignableFrom(UserInfo.class)) { - userInfo = (UserInfo) pjpArgs[i]; - break; - } - } - buildRequestInfo(userInfo, request, requestInfoClass); - buildUserInfo(userInfo, userinfoJson); - UserInfoHolder.set(userInfo); - } - - public String getUserInfoFromToken(String token) { - // postman调用 - String customerEnv = getCustomerEnv(); - customerEnv = CharSequenceUtil.isEmpty(customerEnv) ? AopConstants.ENV_DEV : customerEnv; - String url = EnvEnum.getValueByKey(customerEnv); - AuthException.error(CharSequenceUtil.isNotEmpty(url), "There is no correct path to request"); - - try { - String response = HttpRequest.get(url).header("Authorization", token).execute().body(); - // 使用token获取用户信息 - AuthException.error(CharSequenceUtil.isNotEmpty(response), "not find user by token from pudge"); - return response; - } catch (HttpException e) { - throw new AuthException("call pudge get/user error."); - } - } - - /** - * 从env/properties 获取my_pod_namespace 的value - */ - public String getSystemProperties() { - PodNamespacePropertyDefiner podNamespacePropertyDefiner = new PodNamespacePropertyDefiner(); - return podNamespacePropertyDefiner.getPropertyValue(); - } - - /** - * 从本地拿 CUSTOM_ENV的值 - */ - public String getCustomerEnv() { - PodNamespacePropertyDefiner podNamespacePropertyDefiner = new PodNamespacePropertyDefiner(); - return (String) podNamespacePropertyDefiner.getSystemProperties().get("CUSTOM_ENV"); - } - - @SneakyThrows - private void buildRequestInfo(UserInfo userInfo, HttpServletRequest request, Class requestInfoClass) { - RequestInfo requestInfo = userInfo.getRequestInfo(); - if (Objects.isNull(requestInfo)) { - requestInfo = requestInfoClass.newInstance(); - userInfo.setRequestInfo(requestInfo); - } - // 请求头获取数据 - requestInfo.setAppVersion(request.getHeader(AopConstants.HEADER_APP_VERSION)); - requestInfo.setDeviceKind(request.getHeader(AopConstants.HEADER_DEVICE_KIND)); - requestInfo.setDeviceNo(request.getHeader(AopConstants.HEADER_DEVICE_NO)); - requestInfo.setSystemType(request.getHeader(AopConstants.HEADER_SYSTEM_TYPE)); - requestInfo.setTenantId(request.getHeader(AopConstants.HEADER_TENANT)); - requestInfo.setVisitTo(request.getHeader(AopConstants.VISIT_TO)); - requestInfo.setToken(request.getHeader(AopConstants.HEADER_AUTH)); - String saasTenantId = request.getHeader(AopConstants.HEADER_SAAS_TENANT_ID); - requestInfo.setSaasTenantId(CharSequenceUtil.isEmpty(saasTenantId) ? null : Long.valueOf(saasTenantId)); - String workspaceId = request.getHeader(AopConstants.HEADER_WORKSPACE_ID); - requestInfo.setWorkspaceId(CharSequenceUtil.isEmpty(workspaceId) ? null : Long.valueOf(workspaceId)); - requestInfo.buildCustomRequestInfo(request); - } - - public void buildUserInfo(UserInfo userInfo, String userJsonInfo) { - TypeReference> mapTypeReference = new TypeReference>(){}; - Map map = JSONUtil.toBean(userJsonInfo, mapTypeReference, false); - // 对bean进行封装属性 - BeanUtil.fillBeanWithMap(map, userInfo, false); - - userInfo.buildCustomUserInfo(new UserInfoMap(map)); - - } - -} diff --git a/axzo-auth-spring-boot-starter/src/main/java/cn/axzo/framework/auth/service/ContextInfoBuilderAspect.java b/axzo-auth-spring-boot-starter/src/main/java/cn/axzo/framework/auth/service/ContextInfoBuilderAspect.java new file mode 100644 index 0000000..b34647e --- /dev/null +++ b/axzo-auth-spring-boot-starter/src/main/java/cn/axzo/framework/auth/service/ContextInfoBuilderAspect.java @@ -0,0 +1,180 @@ +package cn.axzo.framework.auth.service; + +import java.lang.reflect.Method; +import java.util.Map; +import java.util.Objects; + +import javax.servlet.http.HttpServletRequest; + +import org.aspectj.lang.ProceedingJoinPoint; +import org.aspectj.lang.annotation.Around; +import org.aspectj.lang.annotation.Aspect; +import org.aspectj.lang.reflect.MethodSignature; +import org.springframework.core.annotation.Order; +import org.springframework.stereotype.Component; +import org.springframework.web.context.request.RequestContextHolder; +import org.springframework.web.context.request.ServletRequestAttributes; + +import cn.axzo.framework.auth.AuthException; +import cn.axzo.framework.auth.annotation.PreBuildContext; +import cn.axzo.framework.auth.constants.AopConstants; +import cn.axzo.framework.auth.domain.ContextInfo; +import cn.axzo.framework.auth.domain.ContextInfoHolder; +import cn.axzo.framework.auth.domain.SystemAndDeviceInfo; +import cn.axzo.framework.auth.domain.UserInfo; +import cn.axzo.framework.auth.domain.UserInfoMap; +import cn.axzo.framework.auth.enums.EnvEnum; +import cn.azxo.framework.common.logger.logback.PodNamespacePropertyDefiner; +import cn.hutool.core.bean.BeanUtil; +import cn.hutool.core.codec.Base64; +import cn.hutool.core.lang.TypeReference; +import cn.hutool.core.text.CharSequenceUtil; +import cn.hutool.http.HttpException; +import cn.hutool.http.HttpRequest; +import cn.hutool.json.JSONUtil; +import lombok.SneakyThrows; +import lombok.extern.slf4j.Slf4j; + +@Slf4j +@Aspect +@Component +@Order(1) +public class ContextInfoBuilderAspect { + + @Around(value = "@within(preBuildContext)") + public Object classHandler(ProceedingJoinPoint pjp, PreBuildContext preBuildContext) { + return handle(pjp, preBuildContext); + } + + @Around(value = "@annotation(preBuildContext)") + public Object methodHandler(ProceedingJoinPoint pjp, PreBuildContext preBuildContext) { + return handle(pjp, preBuildContext); + } + + @SneakyThrows + public Object handle(ProceedingJoinPoint pjp, PreBuildContext preBuildContext) { + HttpServletRequest httpRequest = null; + try { + // 获取request + httpRequest = ((ServletRequestAttributes) Objects + .requireNonNull(RequestContextHolder.getRequestAttributes())).getRequest(); + } catch (Exception exception) { + log.error("can not get request,there is a error occurrence ==>" + exception.getCause().getMessage()); + } + AuthException.error(Objects.nonNull(httpRequest), "httpRequest cant be null, this is error"); + + fillInContextInfoDetail(httpRequest, pjp); + try { + return pjp.proceed(); + } finally { + ContextInfoHolder.clear(); + } + } + + public void fillInContextInfoDetail(HttpServletRequest request, ProceedingJoinPoint pjp) { + String userinfoJson; + // 本地运行 分两种情况 postMan/junit + // 判断本地环境 + if (getSystemProperties() == null) { + // 如果本地环境 有两种如果是postman类型调用手动调用pudge + String token = request.getHeader("Authorization"); + if (CharSequenceUtil.isEmpty(token)) { + // 硬逻辑 如果不携带token 可理解为junit测试 这里不覆盖 Userinfo的信息 + return; + } + userinfoJson = getUserInfoFromToken(token); + } else { + // 走 apisix 获取的请求 + String userJsonInfo = request.getHeader(AopConstants.USER_INFO); + AuthException.error(CharSequenceUtil.isNotEmpty(userJsonInfo), + "do not have userinfo error , please check apisix config is correct"); + // 转编码 + userinfoJson = Base64.decodeStr(userJsonInfo); + } + + ContextInfo contextInfo = new ContextInfo(); + buildUserInfo(contextInfo, userinfoJson); + fillContextInfoWithRequest(contextInfo, request); + contextInfo.buildCustomInfo(request); + ContextInfoHolder.set(contextInfo); + + MethodSignature methodSignature = (MethodSignature) pjp.getSignature(); + Method method = methodSignature.getMethod(); + Class[] parameterTypes = method.getParameterTypes(); + Object[] pjpArgs = pjp.getArgs(); + for (int i = 0; i < parameterTypes.length; i++) { + if (parameterTypes[i].isAssignableFrom(ContextInfo.class)) { + contextInfo = (ContextInfo) pjpArgs[i]; + break; + } + } + + } + + public String getUserInfoFromToken(String token) { + // postman调用 + String customerEnv = getCustomerEnv(); + customerEnv = CharSequenceUtil.isEmpty(customerEnv) ? AopConstants.ENV_DEV : customerEnv; + String url = EnvEnum.getValueByKey(customerEnv); + AuthException.error(CharSequenceUtil.isNotEmpty(url), "There is no correct path to request"); + + try { + String response = HttpRequest.get(url).header("Authorization", token).execute().body(); + // 使用token获取用户信息 + AuthException.error(CharSequenceUtil.isNotEmpty(response), "not find user by token from pudge"); + return response; + } catch (HttpException e) { + throw new AuthException("call pudge get/user error."); + } + } + + /** + * 从env/properties 获取my_pod_namespace 的value + */ + public String getSystemProperties() { + PodNamespacePropertyDefiner podNamespacePropertyDefiner = new PodNamespacePropertyDefiner(); + return podNamespacePropertyDefiner.getPropertyValue(); + } + + /** + * 从本地拿 CUSTOM_ENV的值 + */ + public String getCustomerEnv() { + PodNamespacePropertyDefiner podNamespacePropertyDefiner = new PodNamespacePropertyDefiner(); + return (String) podNamespacePropertyDefiner.getSystemProperties().get("CUSTOM_ENV"); + } + + @SneakyThrows + private void fillContextInfoWithRequest(ContextInfo contextInfo, HttpServletRequest request) { + + SystemAndDeviceInfo sdInfo = new SystemAndDeviceInfo(); + // 请求头获取数据 + sdInfo.setAppVersion(request.getHeader(AopConstants.HEADER_APP_VERSION)); + sdInfo.setDeviceKind(request.getHeader(AopConstants.HEADER_DEVICE_KIND)); + sdInfo.setDeviceNo(request.getHeader(AopConstants.HEADER_DEVICE_NO)); + sdInfo.setSystemType(request.getHeader(AopConstants.HEADER_SYSTEM_TYPE)); + + contextInfo.setSystemAndDeviceInfo(sdInfo); + + contextInfo.setTenantId(request.getHeader(AopConstants.HEADER_TENANT)); + contextInfo.setVisitTo(request.getHeader(AopConstants.VISIT_TO)); + contextInfo.setToken(request.getHeader(AopConstants.HEADER_AUTH)); + String saasTenantId = request.getHeader(AopConstants.HEADER_SAAS_TENANT_ID); + contextInfo.setSaasTenantId(CharSequenceUtil.isEmpty(saasTenantId) ? null : Long.valueOf(saasTenantId)); + String workspaceId = request.getHeader(AopConstants.HEADER_WORKSPACE_ID); + contextInfo.setWorkspaceId(CharSequenceUtil.isEmpty(workspaceId) ? null : Long.valueOf(workspaceId)); + } + + public void buildUserInfo(ContextInfo contextInfo, String userJsonInfo) { + UserInfo userInfo = new UserInfo(); + TypeReference> mapTypeReference = new TypeReference>() { + }; + Map map = JSONUtil.toBean(userJsonInfo, mapTypeReference, false); + // 对bean进行封装属性 + BeanUtil.fillBeanWithMap(map, userInfo, false); + + contextInfo.setUserInfo(userInfo); + contextInfo.buildCustomUserInfo(new UserInfoMap(map)); + } + +} diff --git a/axzo-auth-spring-boot-starter/src/main/resources/META-INF/spring.factories b/axzo-auth-spring-boot-starter/src/main/resources/META-INF/spring.factories index aec11ac..98fab7a 100644 --- a/axzo-auth-spring-boot-starter/src/main/resources/META-INF/spring.factories +++ b/axzo-auth-spring-boot-starter/src/main/resources/META-INF/spring.factories @@ -1 +1 @@ -org.springframework.boot.autoconfigure.EnableAutoConfiguration=cn.axzo.framework.auth.config.UserInfoConfiguration \ No newline at end of file +org.springframework.boot.autoconfigure.EnableAutoConfiguration=cn.axzo.framework.auth.config.ContextInfoConfiguration \ No newline at end of file