package cn.cslg.pas.common.auth; import cn.cslg.pas.common.DataSource; import cn.cslg.pas.common.model.cronModel.PersonnelVO; import cn.cslg.pas.common.utils.CacheUtils; import cn.cslg.pas.common.utils.LoginUtils; import cn.cslg.pas.common.utils.Response; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; import io.swagger.v3.oas.annotations.Operation; import okhttp3.FormBody; import okhttp3.OkHttpClient; import okhttp3.Request; import okhttp3.RequestBody; import org.aspectj.lang.JoinPoint; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Before; 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.stereotype.Component; import javax.script.ScriptEngine; import javax.script.ScriptEngineManager; import java.lang.reflect.Method; import java.util.List; import java.util.Objects; import static cn.cslg.pas.common.utils.JsonUtils.log; @Order(2) @Aspect @Component public class AuthAop { @Value("${authorUrl}") private String url; @Autowired private CacheUtils cacheUtils; @Autowired private LoginUtils loginUtils; /** * 定义切点 */ @Pointcut("@annotation(cn.cslg.pas.common.auth.checkAuth)") public void annotationPointcut() { } /** * @param joinPoint 当前执行的方法 */ @Around("annotationPointcut()") public Object doAround(ProceedingJoinPoint joinPoint) throws Throwable { try { //获得登录人信息 PersonnelVO personnelVO = cacheUtils.getLoginUserPersonnel(loginUtils.getId()); if (personnelVO.getState() == 0) { return Response.error("登录账号已被禁用,请联系管理员启用"); } // 是否通过切面过滤标记 Boolean isPass = true; MethodSignature ms = (MethodSignature) joinPoint.getSignature(); //获得执行方法对象 Method method = ms.getMethod(); //获得执行方法对象上的@checkAuth,@Operation注解对象 checkAuth myAnnotation = method.getAnnotation(checkAuth.class); Operation operAnnotation = method.getAnnotation(Operation.class); //获得@checkAuth注解上FunId参数的值 String functionId = myAnnotation.FunId(); //获得执行方法的参数对象 Object[] args = joinPoint.getArgs(); //根据登录人的id以及功能id获得规则信息 //将登录人的id以及功能id放入requestBody中 RequestBody requestBody = new FormBody.Builder() .add("loginId", loginUtils.getId().toString()) .add("functionId", functionId) .build(); //建立远程连接 OkHttpClient okHttpClient = new OkHttpClient(); //发送请求 Request request = new Request.Builder() .url(url + "/permission/api/data/queryDataRule") .addHeader("Cookie", LoginUtils.getToken()) .post(requestBody) .build(); //获得请求结果 String resBody = Objects.requireNonNull(okHttpClient.newCall(request).execute().body()).string(); JSONArray jsonArray = JSONArray.parseArray(resBody); //如果获得规则的返回值为[-1]则代表登录人没有使用该功能的权限 if (jsonArray.get(0).toString().equals("-1")) { return Response.noPermissions("没有" + operAnnotation.summary() + "的功能"); } //如果获得规则的返回值为[0],则直接通过判断 else if (jsonArray.size() == 1 && jsonArray.get(0).equals("0")) { return joinPoint.proceed(); } // 如果查询结果的size大于0证明有限制逻辑 if (jsonArray.size() > 0) { RequestBody reBodySource = new FormBody.Builder() .add("tableName", "local") .build(); //处理jsonObject,变为(x==y)&&(z==t)的形式 ,并用js引擎进行boolean判断 //建立连接去获得字典信息 OkHttpClient okHttpClientSou = new OkHttpClient(); //发送请求 Request requestSou = new Request.Builder() .url(url + "/permission/api/data/getDataSource") .post(reBodySource) .addHeader("Cookie", LoginUtils.getToken()) .build(); //获得请求返回 String resSource = Objects.requireNonNull(okHttpClientSou.newCall(requestSou).execute().body()).string(); JSONArray jsonArray1 = JSON.parseArray(resSource); // 获得字典 List dataSources = jsonArray1.toJavaList(DataSource.class); //循环遍历将多个规则拼接起来 StringBuilder sqlStr = new StringBuilder(); for (int i = 0; i < jsonArray.size(); i++) { //将数据库里存的规则转换为可识别的判断逻辑 String sql = TreeUtils.reCompute(JSONObject.parseObject(jsonArray.get(i).toString()), args, dataSources, personnelVO); sqlStr.append(jsonArray.size() != i + 1 ? sql + " || " : sql); } //js引擎进行判断 ScriptEngineManager manager = new ScriptEngineManager(); //根据名字获得引擎 ScriptEngine engine = manager.getEngineByName("javascript"); //进行判断,生成判断结果并将判断结果赋给isPass Object result = engine.eval(sqlStr.toString());//进行判断 isPass = (Boolean) result; } //判断不通过 if (!isPass) { return Response.noPermissions("没有权限进行" + operAnnotation.summary() + "的操作"); } //判断通过 return joinPoint.proceed(); } catch (Exception var10) { log.error("operlog exception:{}", var10); return joinPoint.proceed(); } } @Before(value = "annotationPointcut()") public void doAfterReturning(JoinPoint joinPoint) { this.handleAfterLog(joinPoint); } protected void handleAfterLog(JoinPoint joinPoint) { try { log.info("after ----> title:{}, desc:{}",1,2); return; } catch (Exception var10) { log.error("operlog exception:{}", var10); return; } } }