Merge remote-tracking branch 'origin/master-for-apisix' into master-for-apisix

# Conflicts:
#	axzo-auth-spring-boot-starter/src/main/java/cn/axzo/framework/auth/service/BuilderUserInfoAspect.java
This commit is contained in:
zhangtianyu 2022-04-26 16:51:15 +08:00
commit be9eb240e7
8 changed files with 232 additions and 106 deletions

View File

@ -1,100 +0,0 @@
package cn.axzo.framework.auth.service;
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.UserInfoMap;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.codec.Base64;
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.stereotype.Component;
import org.springframework.util.StringUtils;
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
public class BuilderUserInfoAspect {
@Around(value = "@annotation(preBuildUser)")
public Object methodHandler(ProceedingJoinPoint pjp, PreBuildUser preBuildUser) throws Throwable {
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.printStackTrace(););
}
//todo request 为null
assert httpRequest != null;
Class<? extends RequestInfo> requestInfoClass = preBuildUser.requestInfo();
this.fillInUserInfoDetail(httpRequest, pjp, requestInfoClass);
return pjp.proceed();
}
public void fillInUserInfoDetail(HttpServletRequest request, ProceedingJoinPoint pjp, Class<? extends RequestInfo> requestInfoClass) {
String userJsonInfo = request.getHeader(AopConstants.USER_INFO);
//转编码
String userInfo = Base64.decodeStr(userJsonInfo);
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 (UserInfo.class.isAssignableFrom(parameterTypes[i])) {
UserInfo pjpArg = (UserInfo) pjpArgs[i];
buildRequestInfo(pjpArg, request, requestInfoClass);
if (StringUtils.isEmpty(userJsonInfo)) {
//没有拿到用户信息这个构建也没有意义了 //todo 做个异常处理
return;
}
buildUserInfo(pjpArg, userInfo);
break;
}
}
}
@SneakyThrows
private void buildRequestInfo(UserInfo userInfo, HttpServletRequest request, Class<? extends RequestInfo> requestInfoClass) {
RequestInfo requestInfo = userInfo.getRequestInfo();
if (Objects.isNull(requestInfo)) {
requestInfo = requestInfoClass.newInstance();
userInfo.setRequestInfo(requestInfo);
}
// 请求头获取数据
requestInfo.setAppVersion(request.getHeader(AopConstants.HAEDER_APP_VERSION));
requestInfo.setDeviceKind(request.getHeader(AopConstants.HAEDER_DEVICE_KIND));
requestInfo.setDeviceNo(request.getHeader(AopConstants.HAEDER_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));
requestInfo.buildCustomRequestInfo(request);
}
public void buildUserInfo(UserInfo userInfo, String userJsonInfo) {
TypeReference<Map<String, Object>> mapTypeReference = new TypeReference<Map<String, Object>>(){};
Map<String, Object> map = JSONUtil.toBean(userJsonInfo, mapTypeReference, false);
//对bean进行封装属性
BeanUtil.fillBeanWithMap(map, userInfo, false);
userInfo.buildCustomUserInfo(new UserInfoMap(map));
}
}

View File

@ -9,10 +9,10 @@
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>cn.axzo.framework</groupId>
<artifactId>auth-starter</artifactId>
<version>1.0.0</version>
<name>auth-starter</name>
<description>auth-starter</description>
<artifactId>axzo-auth-spring-boot-starter</artifactId>
<version>1.0.1</version>
<name>axzo-auth-spring-boot-starter</name>
<description>axzo-auth-spring-boot-starter</description>
<properties>
<maven.compiler.source>8</maven.compiler.source>
@ -24,6 +24,13 @@
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
<scope>provided</scope>
</dependency>
<dependency>
@ -72,6 +79,13 @@
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>2.0.0-alpha1</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>cn.axzo.framework</groupId>
<artifactId>common-common</artifactId>
<version>1.1.5</version>
</dependency>
</dependencies>

View File

@ -9,6 +9,10 @@ public class AopConstants {
public static final String HAEDER_APP_VERSION = "appVersion";
public static final String VISIT_TO = "visitTo";
public static final String USER_INFO = "userinfo";
public static final String ENV_DEV="dev";

View File

@ -0,0 +1,35 @@
package cn.axzo.framework.auth.enums;
import lombok.AllArgsConstructor;
import lombok.Getter;
@Getter
@AllArgsConstructor
public enum EnvEnum {
// dev
DEV("dev", "http://dev-api.axzo.cn/pudge/webApi/oauth/user"),
// TEST
TEST("TEST", "http://test-api.axzo.cn/pudge/webApi/oauth/user"),
//TEST1
TEST1("TEST1", "http://test1-api.axzo.cn/pudge/webApi/oauth/user"),
//PRE
PRE("PRE", "http://dev-api.axzo.cn/pudge/webApi/oauth/user"),
;
private String key;
private String value;
public static String getValueByKey(String key) {
try {
for(EnvEnum env:EnvEnum.values()) {
if(env.getKey().equals(key)) {
return env.getValue();
}
}
}catch(Exception e) {
return "未知";
}
return "未知";
}
}

View File

@ -0,0 +1,173 @@
package cn.axzo.framework.auth.service;
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.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.util.StrUtil;
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.stereotype.Component;
import org.springframework.util.Assert;
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
public class BuilderUserInfoAspect {
@Around(value = "@annotation(preBuildUser)")
public Object methodHandler(ProceedingJoinPoint pjp, PreBuildUser preBuildUser) throws Throwable {
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());
}
Assert.notNull(httpRequest, "httpReqeust cant be null, this is error");
this.fillInUserInfoDetail(httpRequest, pjp);
//todo request 为null
assert httpRequest != null;
this.fillInUserInfoDetail(httpRequest, pjp, preBuildUser.requestInfo());
return pjp.proceed();
}
public void fillInUserInfoDetail(HttpServletRequest request, ProceedingJoinPoint pjp) {
//请求头获取数据
String tenantId = request.getHeader(AopConstants.HEADER_TENANT);
String systemType = request.getHeader(AopConstants.HEADER_SYSTEM_TYPE);
String authorization = request.getHeader(AopConstants.HEADER_AUTH);
String deviceKind = request.getHeader(AopConstants.HAEDER_DEVICE_KIND);
String deviceNo = request.getHeader(AopConstants.HAEDER_DEVICE_NO);
String appVersion = request.getHeader(AopConstants.HAEDER_APP_VERSION);
String visitTo = request.getHeader(AopConstants.VISIT_TO);
String userinfoJson = "";
//本地运行 分两种情况 postMan/junit
//判断本地环境
if (this.getSystemProperties() == null) {
//如果本地环境 有两种如果是postman类型调用手动调用pudge
String url = "";
String token = request.getHeader("Authorization");
if (StrUtil.isEmpty(token)) {
// 硬逻辑 如果不携带token 可理解为junit测试 这里不覆盖 Userinfo的信息
return;
} else {
//postman调用
String customerEnv = this.getCustomerEnv();
customerEnv = StrUtil.isEmpty(customerEnv) ? AopConstants.ENV_DEV : customerEnv;
url = EnvEnum.getValueByKey(customerEnv);
if (StrUtil.isEmpty(url)) {
throw new RuntimeException("There is no correct path to request");
}
String response = "";
try {
response = HttpRequest.get(url).header("Authorization", token).execute().body();
} catch (HttpException e) {
throw new RuntimeException("call pudge get/user error.");
}
//如果返回了 user信息 进行构建
if (StrUtil.isEmpty(response)) {
throw new RuntimeException("not find user by token from pudge");
}
userinfoJson = response;
}
} else {
// apisix 获取的请求
String userJsonInfo = request.getHeader(AopConstants.USER_INFO);
Assert.notNull(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();
for (int i = 0; i < parameterTypes.length; i++) {
if (parameterTypes[i].isAssignableFrom(UserInfo.class)) {
UserInfo pjpArg = (UserInfo) pjpArgs[i];
buildUserInfoWithAspect(pjpArg, userinfoJson);
//塞一些系统参数
pjpArg.setAppVersion(appVersion);
pjpArg.setDeviceKind(deviceKind);
pjpArg.setDeviceNo(deviceNo);
pjpArg.setSystemType(systemType);
pjpArg.setTenantId(tenantId);
pjpArg.setVisitTo(visitTo);
pjpArg.setToken(authorization);
break;
}
}
}
public void buildUserInfoWithAspect(UserInfo userInfo, String userJsonInfo) {
//todo 直接获取用户信息
Map map = JSONUtil.toBean(userJsonInfo, Map.class);
BeanUtil.fillBeanWithMap(map, userInfo, false);
}
//从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<? extends RequestInfo> requestInfoClass) {
RequestInfo requestInfo = userInfo.getRequestInfo();
if (Objects.isNull(requestInfo)) {
requestInfo = requestInfoClass.newInstance();
userInfo.setRequestInfo(requestInfo);
}
// 请求头获取数据
requestInfo.setAppVersion(request.getHeader(AopConstants.HAEDER_APP_VERSION));
requestInfo.setDeviceKind(request.getHeader(AopConstants.HAEDER_DEVICE_KIND));
requestInfo.setDeviceNo(request.getHeader(AopConstants.HAEDER_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));
requestInfo.buildCustomRequestInfo(request);
}
public void buildUserInfo(UserInfo userInfo, String userJsonInfo) {
TypeReference<Map<String, Object>> mapTypeReference = new TypeReference<Map<String, Object>>(){};
Map<String, Object> map = JSONUtil.toBean(userJsonInfo, mapTypeReference, false);
//对bean进行封装属性
BeanUtil.fillBeanWithMap(map, userInfo, false);
userInfo.buildCustomUserInfo(new UserInfoMap(map));
}
}

View File

@ -0,0 +1 @@
org.springframework.boot.autoconfigure.EnableAutoConfiguration=cn.axzo.framework.auth.config.UserInfoConfiguration

View File

@ -17,8 +17,7 @@
<module>asyncTool</module>
<module>alarm-spring-boot-starter</module>
<module>canal-alarm</module>
<!-- <module>axzo-framewo /rk-auth</module>-->
<module>auth-starter</module>
<module>axzo-auth-spring-boot-starter</module>
</modules>
<build>