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 index 8a649f0..a341e1d 100644 --- 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 @@ -423,9 +423,5 @@ public class TerminalInfo { TerminalInfo tm = new TerminalInfo(terminal); return tm.allNames(); } - - - ////专门用于切换ent、proj这个情况的 - public static final String TEMP_SESSION_KEY_FOR_PERSPECTIVE_BUG = "_temp_terminal_for_perspective_switch_bug_"; } 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 index 426e649..f3d696b 100644 --- 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 @@ -43,6 +43,22 @@ import java.util.Objects; @Order(1) public class ContextInfoBuilderAspect { + /** + * 从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"); + } + @Around(value = "@within(preBuildContext)") public Object classHandler(ProceedingJoinPoint pjp, PreBuildContext preBuildContext) { return handle(pjp, preBuildContext); @@ -66,7 +82,15 @@ public class ContextInfoBuilderAspect { AuthException.error(Objects.nonNull(httpRequest), "httpRequest cant be null, this is error"); try { - ContextInfo contextInfo = fillContextInfoByRequest(httpRequest); + ContextInfo contextInfo = new ContextInfo(); + fillContextInfoWithRequestBeforeRemoteAuth(contextInfo, httpRequest); + + String authResultJson = remoteAuth(httpRequest, contextInfo); + + buildContextInfoByRemoteAuthResponse(contextInfo, authResultJson); + + // 定制一些信息的处理 + contextInfo.buildCustomInfoByRequest(httpRequest); // 把ContextInfo放到ThreadLocal中 ContextInfoHolder.set(contextInfo); Object[] args = parseContextInfoAndReturnArgs(httpRequest, pjp, contextInfo); @@ -99,16 +123,37 @@ public class ContextInfoBuilderAspect { } return pjpArgs; } + - /** - * - * @param request - * @return 如果在本地环境,junit测试状态下,返回null - */ - private ContextInfo fillContextInfoByRequest(HttpServletRequest request) { - ContextInfo contextInfo = new ContextInfo(); - fillContextInfoWithRequest(contextInfo, request); + @SneakyThrows + private void fillContextInfoWithRequestBeforeRemoteAuth(ContextInfo contextInfo, HttpServletRequest request) { + SystemAndDeviceInfo sdInfo = new SystemAndDeviceInfo(); + // 请求头获取数据 + sdInfo.setAppVersion(request.getHeader(AuthConstants.HEADER_APP_VERSION)); + sdInfo.setDeviceKind(request.getHeader(AuthConstants.HEADER_DEVICE_KIND)); + sdInfo.setDeviceNo(request.getHeader(AuthConstants.HEADER_DEVICE_NO)); + sdInfo.setSystemType(request.getHeader(AuthConstants.HEADER_SYSTEM_TYPE)); + sdInfo.setSystemVersion(request.getHeader(AuthConstants.HEADER_SYSTEM_VERSION)); + sdInfo.setIpAddress(IPUtils.getIPAddress(request)); + contextInfo.setSystemAndDeviceInfo(sdInfo); + contextInfo.setToken(request.getHeader(AuthConstants.HEADER_TOKEN)); + + contextInfo.setTenantId(nullSafeParseLong(request.getHeader(AuthConstants.HEADER_TENANT_ID))); + contextInfo.setSaasTenantId(nullSafeParseLong(request.getHeader(AuthConstants.HEADER_SAAS_TENANT_ID))); + contextInfo.setOuId(nullSafeParseLong(request.getHeader(AuthConstants.HEADER_OU_ID))); + contextInfo.setWorkspaceId(nullSafeParseLong(request.getHeader(AuthConstants.HEADER_WORKSPACE_ID))); + + String terminalHeader = request.getHeader(AuthConstants.HEADER_TERMINAL); + contextInfo.setTerminalInfo(new TerminalInfo(terminalHeader)); + + contextInfo.setVisitTo(request.getHeader(AuthConstants.VISIT_TO)); + } + + ////以上都是还没有去remote auth之前的动作 + + + private String remoteAuth(HttpServletRequest httpRequest, ContextInfo contextInfo) { String authResultJson; // 本地运行 分两种情况 postMan/junit // 判断本地环境 @@ -118,25 +163,26 @@ public class ContextInfoBuilderAspect { // 硬逻辑 如果不携带token 可理解为junit测试 这里不覆盖 Userinfo的信息 return null; } - authResultJson = getUserInfoFromPudge(contextInfo, request); + authResultJson = remoteAuthFromPudge(contextInfo, httpRequest); } else { // 走 apisix 获取的请求 - String userJsonInfo = request.getHeader(AuthConstants.USER_INFO); + String userJsonInfo = httpRequest.getHeader(AuthConstants.USER_INFO); AuthException.error(CharSequenceUtil.isNotEmpty(userJsonInfo), "do not have userinfo error , please check apisix config is correct"); // 转编码 authResultJson = Base64.decodeStr(userJsonInfo); } - - buildUserInfo(contextInfo, authResultJson); - - // 定制一些信息的处理 - contextInfo.buildCustomInfoByRequest(request); - - return contextInfo; + return authResultJson; } - - public String getUserInfoFromPudge(ContextInfo contextInfo, HttpServletRequest originalRequest) { + + /** + * 这个函数基本上都是在本地调试的时候才会走到,如果是apisix网关,不会走这个函数。 + * + * @param contextInfo + * @param originalRequest + * @return + */ + public String remoteAuthFromPudge(ContextInfo contextInfo, HttpServletRequest originalRequest) { // postman调用 String customerEnv = getCustomerEnv(); customerEnv = CharSequenceUtil.isEmpty(customerEnv) ? AuthConstants.ENV_DEV : customerEnv; @@ -151,7 +197,7 @@ public class ContextInfoBuilderAspect { // 期待未来前端补齐header之后,删掉这一行,以及相关代码 request = request.header(LegacyGuessMissedReq.HEADER_LEGACY_GUESS, - buildLegacyGuessMissedReqString(contextInfo, originalRequest)); + buildLegacyGuessMissedReqStringForRemoteAuth(contextInfo, originalRequest)); // 为什么会用HEADER_ORIGINAL_URI? // 现在有一些项目级、企业级,我不确定,是否能通过现有的terminal header能做清晰界定 @@ -177,12 +223,11 @@ public class ContextInfoBuilderAspect { } catch (Exception e) { throw new AuthException("解析鉴权认证请求出错, token=" + contextInfo.getToken(), e); } - } catch (HttpException e) { throw new AuthException("call pudge get/user error. token=" + contextInfo.getToken()); } } - + /** * 期待着前端上线之后,header都补齐,这些代码可以全都删掉 * @@ -191,7 +236,7 @@ public class ContextInfoBuilderAspect { * @return */ @Deprecated - private String buildLegacyGuessMissedReqString(ContextInfo contextInfo, HttpServletRequest originalRequest) { + private String buildLegacyGuessMissedReqStringForRemoteAuth(ContextInfo contextInfo, HttpServletRequest originalRequest) { LegacyGuessMissedReq req = new LegacyGuessMissedReq(); req.setOriginalUrl(originalRequest.getRequestURI()); req.setHeaderOuId(contextInfo.getOuId()); @@ -203,73 +248,10 @@ public class ContextInfoBuilderAspect { return JSONUtil.toJsonStr(req); } - /** - * 从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"); - } + ///以下都是 remote auth 之后的动作 - @SneakyThrows - private void fillContextInfoWithRequest(ContextInfo contextInfo, HttpServletRequest request) { - - SystemAndDeviceInfo sdInfo = new SystemAndDeviceInfo(); - // 请求头获取数据 - sdInfo.setAppVersion(request.getHeader(AuthConstants.HEADER_APP_VERSION)); - sdInfo.setDeviceKind(request.getHeader(AuthConstants.HEADER_DEVICE_KIND)); - sdInfo.setDeviceNo(request.getHeader(AuthConstants.HEADER_DEVICE_NO)); - sdInfo.setSystemType(request.getHeader(AuthConstants.HEADER_SYSTEM_TYPE)); - sdInfo.setSystemVersion(request.getHeader(AuthConstants.HEADER_SYSTEM_VERSION)); - sdInfo.setIpAddress(IPUtils.getIPAddress(request)); - contextInfo.setSystemAndDeviceInfo(sdInfo); - - contextInfo.setToken(request.getHeader(AuthConstants.HEADER_TOKEN)); - - contextInfo.setTenantId(nullSafeParseLong(request.getHeader(AuthConstants.HEADER_TENANT_ID))); - contextInfo.setSaasTenantId(nullSafeParseLong(request.getHeader(AuthConstants.HEADER_SAAS_TENANT_ID))); - contextInfo.setOuId(nullSafeParseLong(request.getHeader(AuthConstants.HEADER_OU_ID))); - contextInfo.setWorkspaceId(nullSafeParseLong(request.getHeader(AuthConstants.HEADER_WORKSPACE_ID))); - - String terminal = retrieveTerminalByRequestAndSession(request); - contextInfo.setTerminalInfo(new TerminalInfo(terminal)); - - contextInfo.setVisitTo(request.getHeader(AuthConstants.VISIT_TO)); - } - - private String retrieveTerminalByRequestAndSession(HttpServletRequest request) { - String terminalHeader = request.getHeader(AuthConstants.HEADER_TERMINAL); - String terminalSession = StpUtil.getSession().getString(TerminalInfo.TEMP_SESSION_KEY_FOR_PERSPECTIVE_BUG); - if(null != terminalSession && !"".equals(terminalSession)) { - log.warn("stp.session里面放了临时的legacy terminal,看到这条信息,说明这个BUG还在。"); - //只有一个地方会放内容到这个临时Key里,就是Perspective切换的时候。 - //只要这个东西存在,就以此为准。 - return terminalSession; - } - - String terminalLoginDevice = StpUtil.getLoginDevice(); - if (null == terminalHeader || "".equals(terminalHeader) || "0".equals(terminalHeader)) { - log.warn("请求缺少terminal header,token={}。暂时使用LoginDevice中的补齐terminal={}。", request.getHeader(AuthConstants.HEADER_TOKEN), - terminalSession); - return terminalLoginDevice; - } else if (!TerminalInfo.legacyEquals(terminalHeader, terminalLoginDevice)) { - log.warn("请求缺少terminal header与LoginDevice中不一致,token={}。暂时使用request中的terminal={},LoginDevice terminal={}", - request.getHeader(AuthConstants.HEADER_TOKEN), terminalHeader, terminalLoginDevice); - // terminal = terminalSession; - return terminalHeader; - } - return terminalHeader; - } - - public void buildUserInfo(ContextInfo contextInfo, String authResultJson) { + public void buildContextInfoByRemoteAuthResponse(ContextInfo contextInfo, String authResultJson) { log.info("buildUserInfo-->authResultJson:{},contextInfo:{}", authResultJson, JSONUtil.toJsonStr(contextInfo)); UserInfo userInfo = new UserInfo(); TypeReference> mapTypeReference = new TypeReference>() { @@ -328,6 +310,9 @@ public class ContextInfoBuilderAspect { } } + + ///以下都是工具函数 + public static Long nullSafeParseLong(String input) { if (input == null) return 0L;