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.HttpEntity; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpMethod; import org.springframework.http.ResponseEntity; 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 SsoPowerAspect { @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.SsoPowerAop)") public void ssoPowerPointCut() { } @Around("ssoPowerPointCut()") 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(); SsoPowerAop aop = method.getAnnotation(SsoPowerAop.class) ; if (Objects.nonNull(aop)){ String power = aop.value() ; if(power.trim().equals("")){ power = aop.power() ; } if(power.trim().equals("-1")){ //不进行登录及权限验证 return point.proceed(); }else{ String[] allPower = aop.ifAllPower() ; String[] anyPower = aop.ifAnyPower() ; String token = UserTokenContext.get() ; Object rObj = this.check(token, power, allPower, anyPower); 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 * @param power 一个权限 * @param allPower 多个权限 * @param anyPower 多个权限 * @return 返回对象 */ private Object check(String token, String power, String[] allPower, String[] anyPower){ if(!StringUtils.isNullOrEmpty(SsoCheckUrl)){ String url = UriComponentsBuilder.fromUriString(SsoCheckUrl) .queryParam("token", token) .queryParam("power", power) .queryParam("allPower", (Object) allPower) .queryParam("anyPower", (Object) anyPower) .build() .toUriString(); // 由于获取student接口咱们设置了basicauth,所以需要在请求时配置 HttpHeaders headers = new HttpHeaders(); HttpEntity httpEntity = new HttpEntity<>(headers); ResponseEntity response = null; try { // 通过Get方式调用接口 response = restTemplate.exchange(url, HttpMethod.GET, httpEntity, SsoVo.class); } catch (Exception e) { e.printStackTrace(); } assert response != null; return response.getBody(); }else { return BaseResponseUtils.buildError("后端系统出错,未得到SsoCheckUrl"); } } }