package com.mirage.mirageservice.aspect; import com.mirage.core.annotation.Auth; import com.mirage.core.annotation.WithOriginalResponse; import com.mirage.core.exception.AppRuntimeException; import com.mirage.core.meta.AppCode; import com.mirage.core.meta.AuthType; import com.mirage.core.meta.WebLogBean; import com.mirage.core.utils.AppResult; import com.mirage.core.utils.Constants; import com.mirage.core.utils.GsonUtil; import com.mirage.core.utils.RequestUtil; import com.mirage.mirageservice.domain.CsMinWechatUser; import com.mirage.mirageservice.meta.AppContext; import com.mirage.mirageservice.service.UserService; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Pointcut; import org.aspectj.lang.reflect.MethodSignature; import org.springframework.core.annotation.Order; import org.springframework.data.redis.core.StringRedisTemplate; import org.springframework.stereotype.Component; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.context.request.RequestContextHolder; import org.springframework.web.context.request.ServletRequestAttributes; import javax.annotation.Resource; import javax.servlet.http.HttpServletRequest; import java.lang.annotation.Annotation; import java.lang.reflect.Method; import java.lang.reflect.Parameter; /** * Created by hzlinhai on 2024/5/15. */ @Component @Aspect @Order(value = 1) @Slf4j public class ControllerAround { @Resource private StringRedisTemplate stringRedisTemplate; @Resource private UserService userService; @Pointcut("within(com.mirage.mirageservice.controller..*) " + "&& (@annotation(org.springframework.web.bind.annotation.RequestMapping) " + "|| @annotation(org.springframework.web.bind.annotation.PostMapping))" + "|| @annotation(org.springframework.web.bind.annotation.GetMapping))") private void requestMapping() { } private T getAnnotation(Class clazz, Method method, Class annoClazz) { T annotation = method.getAnnotation(annoClazz); if (annotation == null) { annotation = clazz.getAnnotation(annoClazz); } return annotation; } @Around("requestMapping()") public Object watchRequestMapping(ProceedingJoinPoint jp) { HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest(); AppContext.start(); WebLogBean.start(); WebLogBean logBean = WebLogBean.get(); logBean.setPath(request.getRequestURI()); logBean.setIp(RequestUtil.getIp(request)); logBean.setHeaders(RequestUtil.getHeaders(request)); logBean.setParams(request.getParameterMap()); Object result = null; try { Class clazz = jp.getTarget().getClass(); MethodSignature methodSignature = (MethodSignature) jp.getSignature(); Method method = methodSignature.getMethod(); Object[] args = jp.getArgs(); Parameter[] parameters = method.getParameters(); for (int i = 0; i < parameters.length; i++) { if (parameters[i].getAnnotation(RequestBody.class) != null) { logBean.setPayload(args[i]); break; } } long now = WebLogBean.get().getBeginTime(); Auth auth = getAnnotation(clazz, method, Auth.class); WithOriginalResponse withOriginResponse = getAnnotation(clazz, method, WithOriginalResponse.class); boolean returnOriginData = withOriginResponse != null; String mirageAuth = request.getHeader("MIRAGE-AUTH"); //BussinessAuth 附加Auth(admin) 作用 AuthType authType = auth == null ? null : auth.value(); long startUserFilterTime = System.currentTimeMillis(); // 统一鉴权拦截 if (authType != null) { CsMinWechatUser minWechatUser = null; switch (authType) { case COOKIES: { String debugMod = request.getHeader("MIRAGE-X-DEBUG"); if(StringUtils.isNotBlank(debugMod)){ // userAccount = userService.getUserByAccount("18814867496"); }else{ if(StringUtils.isBlank(mirageAuth)){ throw new AppRuntimeException(AppCode.UNAUTHORIZED); } String sessionValue = stringRedisTemplate.boundValueOps(Constants.REDIS_MIRAGE_LOGIN_SESSION + mirageAuth).get(); if(StringUtils.isBlank(sessionValue)){ throw new AppRuntimeException(AppCode.UNAUTHORIZED); } minWechatUser = GsonUtil.fromJson(sessionValue, CsMinWechatUser.class); if(null == minWechatUser){ throw new AppRuntimeException(AppCode.UNAUTHORIZED); } } break; } case OPEN: { break; } default: { throw new AppRuntimeException(AppCode.FORBIDDEN, "Unsupported Api."); } } // 鉴权信息设置进上下文 AppContext.setUserInfo(minWechatUser); if(null != minWechatUser) { AppContext.setUid(minWechatUser.getId()); logBean.setUid(minWechatUser.getId()); } logBean.addProp("filterCostTimeTotal", System.currentTimeMillis() - startUserFilterTime); } result = jp.proceed(); logBean.setResult(result); if (returnOriginData) { return result; } return new AppResult(result); } catch (AppRuntimeException e) { logBean.setCode(e.getCode()); logBean.setError(e.getMessage()); result = new AppResult(e.getCode(), e.getMessage()); return result; } catch (Throwable e) { log.error("@alert@P0@1min-1@:服务异常#"); log.error(e.getMessage(), e); logBean.setError(e.getMessage()); logBean.setCode(AppCode.UNKNOWN.getCode()); result = new AppResult(AppCode.UNKNOWN.getCode(), AppCode.UNKNOWN.getMessage()); return result; } finally { logBean.setResult(result); AppContext.end(); WebLogBean.end(); } } }