package com.dy.common.aop; import com.dy.common.contant.Constant; import com.dy.common.multiDataSource.DataSourceContext; import com.dy.common.webFilter.UserTokenContext; import com.dy.common.webUtil.BaseResponseUtils; import com.mysql.cj.util.StringUtils; 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.annotation.Pointcut; import org.aspectj.lang.reflect.MethodSignature; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.core.annotation.Order; import org.springframework.http.*; import org.springframework.stereotype.Component; import org.springframework.web.client.RestTemplate; import org.springframework.web.util.UriComponentsBuilder; import java.lang.reflect.Method; import java.util.Objects; @Slf4j @Aspect @Order(Constant.AspectOrderSsoAutho) @Component public class SsoAspect { @Value("${pipIrr.global.dev}") public String isDevStage ;//是否为开发阶段 @Value("${pipIrr.sso.checkUrl}") public String ssoCheckUrl; private RestTemplate restTemplate; @Autowired public void setRestTemplate(RestTemplate restTemplate){ this.restTemplate = restTemplate ; } @Pointcut("@annotation(com.dy.common.aop.SsoAop)") public void ssoPointCut() { } @Around("ssoPointCut()") public Object execute(ProceedingJoinPoint point) throws Throwable { if(isDevStage != null && !isDevStage.trim().equals("") && isDevStage.trim().equalsIgnoreCase("true")){ return point.proceed(); }else{ MethodSignature signature = (MethodSignature) point.getSignature(); Method method = signature.getMethod(); SsoAop aop = method.getAnnotation(SsoAop.class) ; if (Objects.nonNull(aop)){ String token = UserTokenContext.get() ; Object rObj = this.check(token); if(rObj != null){ if(rObj instanceof SsoVo ssoVo){ if(ssoVo.logined){ if(ssoVo.hasPower){ if(!StringUtils.isNullOrEmpty(ssoVo.dataSourceName)){ DataSourceContext.set(ssoVo.dataSourceName); Object obj = point.proceed(); DataSourceContext.remove(); return obj ; }else{ //无数据源 return BaseResponseUtils.buildError("后端系统出错,未得到当前登录用户所属机构标签(数据源名)") ; } }else{ //无权限 return BaseResponseUtils.buildNoPower() ; } }else{ //未登录 return BaseResponseUtils.buildToLogin() ; } }else{ return rObj ; } }else{ return BaseResponseUtils.buildError("后端系统出错,check方法返回null") ; } }else{ //已经进入注解处理了,还得不到注解,这种情况是不可能的。 return BaseResponseUtils.buildError("后端系统出错,DyAop注解为null") ; } } } /** * 调用SSO系统进行验证 * @param token Header中的用户token * @return 返回对象 */ private Object check(String token){ if(!StringUtils.isNullOrEmpty(ssoCheckUrl)){ String url = UriComponentsBuilder.fromUriString(ssoCheckUrl) .queryParam("token", token) .build() .toUriString(); HttpHeaders headers = new HttpHeaders(); headers.setContentType(MediaType.parseMediaType("application/json;charset=UTF-8")); HttpEntity httpEntity = new HttpEntity<>(headers); ResponseEntity response = null; try { // 通过Get方式调用接口 response = restTemplate.exchange(url, HttpMethod.GET, httpEntity, SsoVo.class); } catch (Exception e) { e.printStackTrace(); return BaseResponseUtils.buildError("后端系统出错,访问单点登录系统异常"); } if(response == null){ return BaseResponseUtils.buildError("后端系统出错,访问单点登录系统异常"); }else{ return response.getBody(); } }else { return BaseResponseUtils.buildError("后端系统出错,未得到SsoCheckUrl"); } } }