refactor remote auth

This commit is contained in:
Gao Wei 2022-06-15 20:03:52 +08:00
parent 7000340116
commit f7826741ff
2 changed files with 74 additions and 93 deletions

View File

@ -423,9 +423,5 @@ public class TerminalInfo {
TerminalInfo tm = new TerminalInfo(terminal);
return tm.allNames();
}
////专门用于切换entproj这个情况的
public static final String TEMP_SESSION_KEY_FOR_PERSPECTIVE_BUG = "_temp_terminal_for_perspective_switch_bug_";
}

View File

@ -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 headertoken={}。暂时使用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<Map<String, Object>> mapTypeReference = new TypeReference<Map<String, Object>>() {
@ -328,6 +310,9 @@ public class ContextInfoBuilderAspect {
}
}
///以下都是工具函数
public static Long nullSafeParseLong(String input) {
if (input == null)
return 0L;