diff --git a/epmet-commons/epmet-commons-mybatis/src/main/java/com/epmet/commons/mybatis/aspect/DataFilterAspect.java b/epmet-commons/epmet-commons-mybatis/src/main/java/com/epmet/commons/mybatis/aspect/DataFilterAspect.java index dcb26335ed..ce4cde92b7 100644 --- a/epmet-commons/epmet-commons-mybatis/src/main/java/com/epmet/commons/mybatis/aspect/DataFilterAspect.java +++ b/epmet-commons/epmet-commons-mybatis/src/main/java/com/epmet/commons/mybatis/aspect/DataFilterAspect.java @@ -9,15 +9,14 @@ package com.epmet.commons.mybatis.aspect; import com.epmet.commons.mybatis.annotation.DataFilter; +import com.epmet.commons.mybatis.feign.MybatisGovAccessFeignClient; import com.epmet.commons.tools.constant.AccessSettingConstant; import com.epmet.commons.tools.constant.OpeScopeConstant; import com.epmet.commons.mybatis.dto.form.*; -import com.epmet.commons.mybatis.feign.GovAccessFeignClient; -import com.epmet.commons.mybatis.feign.GovOrgFeignClient; -import com.epmet.commons.tools.aspect.AccessOpeAspect; +import com.epmet.commons.tools.constant.ThreadLocalConstant; +import com.epmet.commons.tools.dto.form.LoginUserInfoResultDTO; import com.epmet.commons.tools.exception.EpmetErrorCode; import com.epmet.commons.tools.exception.RenException; -import com.epmet.commons.tools.security.user.LoginUserUtil; import com.epmet.commons.tools.utils.Result; import org.apache.commons.lang3.ArrayUtils; import org.apache.commons.lang3.StringUtils; @@ -32,7 +31,6 @@ import org.springframework.stereotype.Component; import org.springframework.util.CollectionUtils; import java.util.*; -import java.util.stream.Collectors; /** * 数据过滤,切面处理类 @@ -51,30 +49,19 @@ public class DataFilterAspect { */ private static final ThreadLocal hasConditions = new ThreadLocal(); - /** - * 用于向DataFilterInterceptor传递权限过滤的sql片段(需要在Controller相关的AOP中进行清理,防止变量残留) - */ - public static final ThreadLocal sqlFilter = new ThreadLocal(); - - //public static final ThreadLocal gridIdTL = new ThreadLocal(); - //public static final ThreadLocal deptIdTL = new ThreadLocal(); - - @Autowired - private LoginUserUtil loginUserUtil; - - @Autowired - private GovAccessFeignClient govAccessFeignClient; - @Autowired - private GovOrgFeignClient govOrgFeignClient; - - public static final String orgIdPathSpliter = ":"; + private MybatisGovAccessFeignClient govAccessFeignClient; @Before("@annotation(com.epmet.commons.mybatis.annotation.DataFilter)") public void dataFilter(JoinPoint point) { - //清空 - //sqlFilter.remove(); + // 从ThreadLocal中取所需权限 + String requirePermission = ThreadLocalConstant.requirePermissionTl.get(); + // 没有配置所需权限,不做操作,打印提示日志 + if (StringUtils.isBlank(requirePermission)) { + log.warn("接口缺少所需权限配置,请在Controller方法上使用@RequirePermission注解完成所需权限配置"); + return; + } // 取到注解属性 MethodSignature methodSignature = (MethodSignature) point.getSignature(); @@ -101,48 +88,22 @@ public class DataFilterAspect { } } - // 从ThreadLocal中取所需权限 - String requirePermission = AccessOpeAspect.requirePermissionTl.get(); - // 没有配置所需权限,不做操作,打印提示日志 - if (StringUtils.isBlank(requirePermission)) { - log.warn("接口缺少所需权限配置,请在Controller方法上使用@RequirePermission注解完成所需权限配置"); - return; - } - - String app = loginUserUtil.getLoginUserApp(); - String client = loginUserUtil.getLoginUserClient(); - String userId = loginUserUtil.getLoginUserId(); - - StaffPermCacheFormDTO staffPermissionFormDTO = new StaffPermCacheFormDTO(); - staffPermissionFormDTO.setApp(app); - staffPermissionFormDTO.setClient(client); - staffPermissionFormDTO.setStaffId(userId); - Result result = govAccessFeignClient.getLoginUserInfo(staffPermissionFormDTO); - - if (result.getCode() != 0) { - // 查询不到权限,记录日志,抛出8000异常 - log.error("调用Access查询权限失败:{}", result.getMsg()); - throw new RenException(EpmetErrorCode.SERVER_ERROR.getCode()); - } - - LoginUserInfoResultDTO userDetail = result.getData(); - - if (userDetail == null) { - log.error("操作权限不足,查询不到登录用户信息"); - throw new RenException(EpmetErrorCode.REQUIRE_PERMISSION.getCode()); - } - - Set currPermissions = getPermissions(userDetail.getRoleIdList()); - - // 校验操作权限 - validateOpePermission(currPermissions, requirePermission); + LoginUserInfoResultDTO loginUserInfo = ThreadLocalConstant.loginUserInfoTl.get(); hasConditions.set(false); // 生成过滤sql - String sqlFilterSegment = getSqlFilterSegment(userId, userDetail.getRoleIdList(), requirePermission, - userDetail.getOrgIdPath(), userDetail.getGridIdList(), tableAlias, userDetail.getDeptIdList(), - gridId, deptId, requirePermission); + String sqlFilterSegment = getSqlFilterSegment( + loginUserInfo.getUserId(), + loginUserInfo.getRoleIdList(), + requirePermission, + loginUserInfo.getOrgIdPath(), + loginUserInfo.getGridIdList(), + tableAlias, + loginUserInfo.getDeptIdList(), + gridId, + deptId, + requirePermission); // 方式1.填充到Service方法列表中的DataScope对象中。如果dao入参是用DTO的话,那么再加一个DataScope入参,sql中会报错提示#{}参数找不到,因此改用方法2 //Object[] methodArgs = point.getArgs(); @@ -155,34 +116,7 @@ public class DataFilterAspect { // 方式2,采用ThreadLocal传参到DataFilterInterceptor中 if (StringUtils.isNotBlank(sqlFilterSegment)) { - sqlFilter.set(sqlFilterSegment); - } - } - - private Set getPermissions(Set roleIdList) { - Set permissions = new HashSet<>(); - roleIdList.forEach(role -> { - // 找出该角色的所有功能操作列表 - Result> result = govAccessFeignClient.listRoleAllOperationScopesByRoleId(role); - if (!result.success()) { - // 获取operation异常 - log.error("调用GovAccess,根据RoleId查询Operation列表失败:{}", result.getMsg()); - throw new RenException(EpmetErrorCode.SERVER_ERROR.getCode()); - } - List roleOperations = result.getData(); - permissions.addAll(roleOperations.stream().map(ope -> ope.getOperationKey()).collect(Collectors.toSet())); - }); - return permissions; - } - - /** - * 校验操作权限 - */ - private void validateOpePermission(Set permissions, String reqiurePermission) { - if (!permissions.contains(reqiurePermission)) { - // 权限不足 - log.error("操作权限不足"); - throw new RenException(EpmetErrorCode.REQUIRE_PERMISSION.getCode()); + ThreadLocalConstant.sqlFilter.set(sqlFilterSegment); } } diff --git a/epmet-commons/epmet-commons-mybatis/src/main/java/com/epmet/commons/mybatis/aspect/DataFilterAspectBak.java b/epmet-commons/epmet-commons-mybatis/src/main/java/com/epmet/commons/mybatis/aspect/DataFilterAspectBak.java deleted file mode 100644 index 2c4c532bda..0000000000 --- a/epmet-commons/epmet-commons-mybatis/src/main/java/com/epmet/commons/mybatis/aspect/DataFilterAspectBak.java +++ /dev/null @@ -1,106 +0,0 @@ -///** -// * Copyright (c) 2018 人人开源 All rights reserved. -// * -// * https://www.renren.io -// * -// * 版权所有,侵权必究! -// */ -// -//package com.epmet.commons.mybatis.aspect; -// -//import cn.hutool.core.collection.CollUtil; -//import com.epmet.commons.mybatis.annotation.DataFilter; -//import com.epmet.commons.mybatis.entity.DataScope; -//import com.epmet.commons.tools.constant.Constant; -//import com.epmet.commons.tools.enums.SuperAdminEnum; -//import com.epmet.commons.tools.exception.ErrorCode; -//import com.epmet.commons.tools.exception.RenException; -//import com.epmet.commons.tools.security.user.SecurityUser; -//import com.epmet.commons.tools.security.user.UserDetail; -//import org.apache.commons.lang3.StringUtils; -//import org.aspectj.lang.JoinPoint; -//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.stereotype.Component; -// -//import java.util.Arrays; -//import java.util.List; -//import java.util.Map; -// -///** -// * 数据过滤,切面处理类 -// * -// * @author Mark sunlightcs@gmail.com -// * @since 1.0.0 -// */ -//@Aspect -//@Component -//public class DataFilterAspectBak { -// @Pointcut("@annotation(com.epmet.commons.mybatis.annotation.DataFilter)") -// public void dataFilterCut() { -// -// } -// -// @Before("dataFilterCut()") -// public void dataFilter(JoinPoint point) { -// Object params = point.getArgs()[0]; -// if(params != null && params instanceof Map){ -// UserDetail user = SecurityUser.getUser(); -// -// //如果不是超级管理员,则进行数据过滤 -// if(user.getSuperAdmin() == SuperAdminEnum.NO.value()){ -// Map map = (Map)params; -// String sqlFilter = getSqlFilter(user, point); -// map.put(Constant.SQL_FILTER, new DataScope(sqlFilter)); -// } -// -// return ; -// } -// -// throw new RenException(ErrorCode.DATA_SCOPE_PARAMS_ERROR); -// } -// -// /** -// * 获取数据过滤的SQL -// */ -// private String getSqlFilter(UserDetail user, JoinPoint point){ -// MethodSignature signature = (MethodSignature) point.getSignature(); -// DataFilter dataFilter = signature.getMethod().getAnnotation(DataFilter.class); -// //获取表的别名 -// String tableAlias = dataFilter.tableAlias(); -// if(StringUtils.isNotBlank(tableAlias)){ -// tableAlias += "."; -// } -// -// StringBuilder sqlFilter = new StringBuilder(); -// -// //查询条件前缀 -// String prefix = dataFilter.prefix(); -// if(StringUtils.isNotBlank(prefix)){ -// sqlFilter.append(" ").append(prefix); -// } -// -// sqlFilter.append(" ("); -// -// //部门ID列表 -// List deptIdList = user.getDeptIdList(); -// if(CollUtil.isNotEmpty(deptIdList)){ -// sqlFilter.append(tableAlias).append(dataFilter.deptId()); -// -// sqlFilter.append(" in(").append(StringUtils.join(deptIdList, ",")).append(")"); -// } -// -// //查询本人数据 -// if (dataFilter.isPendingCreator()) { -// if(CollUtil.isNotEmpty(deptIdList)){ -// sqlFilter.append(" or "); -// } -// sqlFilter.append(tableAlias).append(dataFilter.userId()).append("=").append(user.getId()); -// } -// sqlFilter.append(")"); -// -// return sqlFilter.toString(); -// } -//} diff --git a/epmet-commons/epmet-commons-mybatis/src/main/java/com/epmet/commons/mybatis/feign/GovAccessFeignClient.java b/epmet-commons/epmet-commons-mybatis/src/main/java/com/epmet/commons/mybatis/feign/MybatisGovAccessFeignClient.java similarity index 75% rename from epmet-commons/epmet-commons-mybatis/src/main/java/com/epmet/commons/mybatis/feign/GovAccessFeignClient.java rename to epmet-commons/epmet-commons-mybatis/src/main/java/com/epmet/commons/mybatis/feign/MybatisGovAccessFeignClient.java index adac03e71c..91e7743f4e 100644 --- a/epmet-commons/epmet-commons-mybatis/src/main/java/com/epmet/commons/mybatis/feign/GovAccessFeignClient.java +++ b/epmet-commons/epmet-commons-mybatis/src/main/java/com/epmet/commons/mybatis/feign/MybatisGovAccessFeignClient.java @@ -1,13 +1,12 @@ package com.epmet.commons.mybatis.feign; import com.epmet.commons.mybatis.dto.form.*; -import com.epmet.commons.mybatis.feign.fallback.GovAccessFeignClientFallback; +import com.epmet.commons.mybatis.feign.fallback.MybatisGovAccessFeignClientFallback; import com.epmet.commons.tools.constant.ServiceConstant; import com.epmet.commons.tools.utils.Result; import org.springframework.cloud.openfeign.FeignClient; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.RequestBody; import java.util.List; import java.util.Map; @@ -18,15 +17,8 @@ import java.util.Set; * @Author sun */ //, url = "localhost:8099" -@FeignClient(name = ServiceConstant.GOV_ACCESS_SERVER, fallback = GovAccessFeignClientFallback.class) -public interface GovAccessFeignClient { - - /** - * 查询用户当前权限列表 - * @return - */ - @PostMapping("/gov/access/access/loginuserinfo") - Result getLoginUserInfo(@RequestBody StaffPermCacheFormDTO dto); +@FeignClient(name = ServiceConstant.GOV_ACCESS_SERVER, fallback = MybatisGovAccessFeignClientFallback.class) +public interface MybatisGovAccessFeignClient { /** * 查询角色的操作key对应操作范围列表 diff --git a/epmet-commons/epmet-commons-mybatis/src/main/java/com/epmet/commons/mybatis/feign/GovOrgFeignClient.java b/epmet-commons/epmet-commons-mybatis/src/main/java/com/epmet/commons/mybatis/feign/MybatisGovOrgFeignClient.java similarity index 72% rename from epmet-commons/epmet-commons-mybatis/src/main/java/com/epmet/commons/mybatis/feign/GovOrgFeignClient.java rename to epmet-commons/epmet-commons-mybatis/src/main/java/com/epmet/commons/mybatis/feign/MybatisGovOrgFeignClient.java index 67226cdd0e..c912ab332c 100644 --- a/epmet-commons/epmet-commons-mybatis/src/main/java/com/epmet/commons/mybatis/feign/GovOrgFeignClient.java +++ b/epmet-commons/epmet-commons-mybatis/src/main/java/com/epmet/commons/mybatis/feign/MybatisGovOrgFeignClient.java @@ -1,8 +1,7 @@ package com.epmet.commons.mybatis.feign; import com.epmet.commons.mybatis.dto.form.*; -import com.epmet.commons.mybatis.feign.fallback.GovAccessFeignClientFallback; -import com.epmet.commons.mybatis.feign.fallback.GovOrgFeignClientFallback; +import com.epmet.commons.mybatis.feign.fallback.MybatisGovOrgFeignClientFallback; import com.epmet.commons.tools.constant.ServiceConstant; import com.epmet.commons.tools.utils.Result; import org.springframework.cloud.openfeign.FeignClient; @@ -17,8 +16,8 @@ import java.util.Set; * @Author sun */ //, url = "localhost:8092" -@FeignClient(name = ServiceConstant.GOV_ORG_SERVER, fallback = GovOrgFeignClientFallback.class) -public interface GovOrgFeignClient { +@FeignClient(name = ServiceConstant.GOV_ORG_SERVER, fallback = MybatisGovOrgFeignClientFallback.class) +public interface MybatisGovOrgFeignClient { /** * 查询人员部门列表 diff --git a/epmet-commons/epmet-commons-mybatis/src/main/java/com/epmet/commons/mybatis/feign/fallback/GovAccessFeignClientFallback.java b/epmet-commons/epmet-commons-mybatis/src/main/java/com/epmet/commons/mybatis/feign/fallback/MybatisGovAccessFeignClientFallback.java similarity index 78% rename from epmet-commons/epmet-commons-mybatis/src/main/java/com/epmet/commons/mybatis/feign/fallback/GovAccessFeignClientFallback.java rename to epmet-commons/epmet-commons-mybatis/src/main/java/com/epmet/commons/mybatis/feign/fallback/MybatisGovAccessFeignClientFallback.java index 48b25f74f8..15562aa607 100644 --- a/epmet-commons/epmet-commons-mybatis/src/main/java/com/epmet/commons/mybatis/feign/fallback/GovAccessFeignClientFallback.java +++ b/epmet-commons/epmet-commons-mybatis/src/main/java/com/epmet/commons/mybatis/feign/fallback/MybatisGovAccessFeignClientFallback.java @@ -1,7 +1,7 @@ package com.epmet.commons.mybatis.feign.fallback; import com.epmet.commons.mybatis.dto.form.*; -import com.epmet.commons.mybatis.feign.GovAccessFeignClient; +import com.epmet.commons.mybatis.feign.MybatisGovAccessFeignClient; import com.epmet.commons.tools.constant.ServiceConstant; import com.epmet.commons.tools.utils.ModuleUtils; import com.epmet.commons.tools.utils.Result; @@ -19,12 +19,7 @@ import java.util.Set; * @Date 2020/4/24 11:17 **/ @Component -public class GovAccessFeignClientFallback implements GovAccessFeignClient { - - @Override - public Result getLoginUserInfo(StaffPermCacheFormDTO dto) { - return ModuleUtils.feignConError(ServiceConstant.GOV_ACCESS_SERVER, "getLoginUserInfo", dto); - } +public class MybatisGovAccessFeignClientFallback implements MybatisGovAccessFeignClient { @Override public Result> getOperationScopesByRoleId(OperationScopeFormDTO operationScopeFormDTO) { diff --git a/epmet-commons/epmet-commons-mybatis/src/main/java/com/epmet/commons/mybatis/feign/fallback/GovOrgFeignClientFallback.java b/epmet-commons/epmet-commons-mybatis/src/main/java/com/epmet/commons/mybatis/feign/fallback/MybatisGovOrgFeignClientFallback.java similarity index 78% rename from epmet-commons/epmet-commons-mybatis/src/main/java/com/epmet/commons/mybatis/feign/fallback/GovOrgFeignClientFallback.java rename to epmet-commons/epmet-commons-mybatis/src/main/java/com/epmet/commons/mybatis/feign/fallback/MybatisGovOrgFeignClientFallback.java index cce3d60309..dbe95f21eb 100644 --- a/epmet-commons/epmet-commons-mybatis/src/main/java/com/epmet/commons/mybatis/feign/fallback/GovOrgFeignClientFallback.java +++ b/epmet-commons/epmet-commons-mybatis/src/main/java/com/epmet/commons/mybatis/feign/fallback/MybatisGovOrgFeignClientFallback.java @@ -1,8 +1,7 @@ package com.epmet.commons.mybatis.feign.fallback; import com.epmet.commons.mybatis.dto.form.*; -import com.epmet.commons.mybatis.feign.GovAccessFeignClient; -import com.epmet.commons.mybatis.feign.GovOrgFeignClient; +import com.epmet.commons.mybatis.feign.MybatisGovOrgFeignClient; import com.epmet.commons.tools.constant.ServiceConstant; import com.epmet.commons.tools.utils.ModuleUtils; import com.epmet.commons.tools.utils.Result; @@ -18,7 +17,7 @@ import java.util.Set; * @Date 2020/4/24 11:17 **/ @Component -public class GovOrgFeignClientFallback implements GovOrgFeignClient { +public class MybatisGovOrgFeignClientFallback implements MybatisGovOrgFeignClient { @Override public Result> getDepartmentListByStaffId(String staffId) { diff --git a/epmet-commons/epmet-commons-mybatis/src/main/java/com/epmet/commons/mybatis/interceptor/DataFilterInterceptor.java b/epmet-commons/epmet-commons-mybatis/src/main/java/com/epmet/commons/mybatis/interceptor/DataFilterInterceptor.java index 06bc27ea53..ad3fbf2249 100644 --- a/epmet-commons/epmet-commons-mybatis/src/main/java/com/epmet/commons/mybatis/interceptor/DataFilterInterceptor.java +++ b/epmet-commons/epmet-commons-mybatis/src/main/java/com/epmet/commons/mybatis/interceptor/DataFilterInterceptor.java @@ -11,6 +11,7 @@ package com.epmet.commons.mybatis.interceptor; import com.baomidou.mybatisplus.core.toolkit.PluginUtils; import com.baomidou.mybatisplus.extension.handlers.AbstractSqlParserHandler; import com.epmet.commons.mybatis.aspect.DataFilterAspect; +import com.epmet.commons.tools.constant.ThreadLocalConstant; import org.apache.commons.lang3.StringUtils; import org.apache.ibatis.executor.statement.StatementHandler; import org.apache.ibatis.mapping.BoundSql; @@ -78,7 +79,7 @@ public class DataFilterInterceptor extends AbstractSqlParserHandler implements I */ // 方式2.从ThreadLocal中取sqlFilter - String sqlFilter = DataFilterAspect.sqlFilter.get(); + String sqlFilter = ThreadLocalConstant.sqlFilter.get(); if (StringUtils.isBlank(sqlFilter)) { return invocation.proceed(); diff --git a/epmet-commons/epmet-commons-mybatis/src/main/java/com/epmet/commons/mybatis/interceptor/DataFilterInterceptorBak.java b/epmet-commons/epmet-commons-mybatis/src/main/java/com/epmet/commons/mybatis/interceptor/DataFilterInterceptorBak.java deleted file mode 100644 index 1a3445f0f5..0000000000 --- a/epmet-commons/epmet-commons-mybatis/src/main/java/com/epmet/commons/mybatis/interceptor/DataFilterInterceptorBak.java +++ /dev/null @@ -1,100 +0,0 @@ -///** -// * Copyright (c) 2018 人人开源 All rights reserved. -// *

-// * https://www.renren.io -// *

-// * 版权所有,侵权必究! -// */ -// -//package com.epmet.commons.mybatis.interceptor; -// -//import com.baomidou.mybatisplus.core.toolkit.PluginUtils; -//import com.baomidou.mybatisplus.extension.handlers.AbstractSqlParserHandler; -//import com.epmet.commons.mybatis.entity.DataScope; -//import org.apache.ibatis.executor.statement.StatementHandler; -//import org.apache.ibatis.mapping.BoundSql; -//import org.apache.ibatis.mapping.MappedStatement; -//import org.apache.ibatis.mapping.SqlCommandType; -//import org.apache.ibatis.plugin.*; -//import org.apache.ibatis.reflection.MetaObject; -//import org.apache.ibatis.reflection.SystemMetaObject; -// -//import java.sql.Connection; -//import java.util.Map; -//import java.util.Properties; -// -///** -// * 数据过滤 -// * -// * @author Mark sunlightcs@gmail.com -// * @since 1.0.0 -// */ -//@Intercepts({@Signature(type = StatementHandler.class, method = "prepare", args = {Connection.class, Integer.class})}) -//public class DataFilterInterceptorBak extends AbstractSqlParserHandler implements Interceptor { -// -// @Override -// public Object intercept(Invocation invocation) throws Throwable { -// StatementHandler statementHandler = (StatementHandler) PluginUtils.realTarget(invocation.getTarget()); -// MetaObject metaObject = SystemMetaObject.forObject(statementHandler); -// -// // SQL解析 -// this.sqlParser(metaObject); -// -// // 先判断是不是SELECT操作 -// MappedStatement mappedStatement = (MappedStatement) metaObject.getValue("delegate.mappedStatement"); -// if (!SqlCommandType.SELECT.equals(mappedStatement.getSqlCommandType())) { -// return invocation.proceed(); -// } -// -// // 针对定义了rowBounds,做为mapper接口方法的参数 -// BoundSql boundSql = (BoundSql) metaObject.getValue("delegate.boundSql"); -// String originalSql = boundSql.getSql(); -// Object paramObj = boundSql.getParameterObject(); -// -// // 判断参数里是否有DataScope对象 -// DataScope scope = null; -// if (paramObj instanceof DataScope) { -// scope = (DataScope) paramObj; -// } else if (paramObj instanceof Map) { -// for (Object arg : ((Map) paramObj).values()) { -// if (arg instanceof DataScope) { -// scope = (DataScope) arg; -// break; -// } -// } -// } -// -// // 不用数据过滤 -// if (scope == null) { -// return invocation.proceed(); -// } -// -// // 拼接新SQL -// String orderBy = "ORDER BY"; -// String groupBy = "GROUP BY"; -// if (originalSql.indexOf(groupBy) > -1) { -// originalSql = originalSql.replace(groupBy, scope.getSqlFilter() + groupBy); -// } else if (originalSql.indexOf(orderBy) > -1) { -// originalSql = originalSql.replace(orderBy, scope.getSqlFilter() + orderBy); -// } else { -// originalSql = originalSql + scope.getSqlFilter(); -// } -// -// // 重写SQL -// metaObject.setValue("delegate.boundSql.sql", originalSql); -// return invocation.proceed(); -// } -// -// @Override -// public Object plugin(Object target) { -// if (target instanceof StatementHandler) { -// return Plugin.wrap(target, this); -// } -// return target; -// } -// -// @Override -// public void setProperties(Properties properties) { -// -// } -//} diff --git a/epmet-commons/epmet-commons-tools/src/main/java/com/epmet/commons/tools/aspect/AccessOpeAspect.java b/epmet-commons/epmet-commons-tools/src/main/java/com/epmet/commons/tools/aspect/AccessOpeAspect.java deleted file mode 100644 index 054710d348..0000000000 --- a/epmet-commons/epmet-commons-tools/src/main/java/com/epmet/commons/tools/aspect/AccessOpeAspect.java +++ /dev/null @@ -1,45 +0,0 @@ -/** - * Copyright (c) 2018 人人开源 All rights reserved. - * - * https://www.renren.io - * - * 版权所有,侵权必究! - */ - -package com.epmet.commons.tools.aspect; - -import com.epmet.commons.tools.annotation.RequirePermission; -import com.epmet.commons.tools.enums.RequirePermissionEnum; -import org.aspectj.lang.JoinPoint; -import org.aspectj.lang.annotation.Aspect; -import org.aspectj.lang.annotation.Before; -import org.aspectj.lang.reflect.MethodSignature; -import org.springframework.stereotype.Component; - -/** - * 每次请求,过滤Api中配置的权限key出来 - * @Author wxz - * @Description - * @Date 2020/4/23 16:16 - **/ -@Aspect -@Component -public class AccessOpeAspect { - - /** - * 存储所需操作权限的 ThreadLocal - */ - public static final ThreadLocal requirePermissionTl = new ThreadLocal<>(); - - @Before("@annotation(com.epmet.commons.tools.annotation.RequirePermission)") - public void before(JoinPoint point) throws Throwable { - // 取RequirePermission注解 - MethodSignature methodSignature = (MethodSignature) point.getSignature(); - RequirePermission requirePermissionAnno = methodSignature.getMethod().getAnnotation(RequirePermission.class); - RequirePermissionEnum requirePermissionEnum = requirePermissionAnno.requirePermission(); - String key = requirePermissionEnum.getKey(); - - // 放入ThreadLocal,供DataFilterAspect中使用 - requirePermissionTl.set(key); - } -} diff --git a/epmet-commons/epmet-commons-tools/src/main/java/com/epmet/commons/tools/aspect/RequirePermissionAspect.java b/epmet-commons/epmet-commons-tools/src/main/java/com/epmet/commons/tools/aspect/RequirePermissionAspect.java new file mode 100644 index 0000000000..dca14ce55f --- /dev/null +++ b/epmet-commons/epmet-commons-tools/src/main/java/com/epmet/commons/tools/aspect/RequirePermissionAspect.java @@ -0,0 +1,132 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package com.epmet.commons.tools.aspect; + +import com.epmet.commons.tools.annotation.RequirePermission; +import com.epmet.commons.tools.constant.ThreadLocalConstant; +import com.epmet.commons.tools.dto.form.LoginUserInfoFormDTO; +import com.epmet.commons.tools.dto.form.LoginUserInfoResultDTO; +import com.epmet.commons.tools.dto.form.RoleOpeScopeResultDTO; +import com.epmet.commons.tools.enums.RequirePermissionEnum; +import com.epmet.commons.tools.exception.EpmetErrorCode; +import com.epmet.commons.tools.exception.RenException; +import com.epmet.commons.tools.feign.CommonGovAccessFeignClient; +import com.epmet.commons.tools.security.user.LoginUserUtil; +import com.epmet.commons.tools.utils.Result; +import org.aspectj.lang.JoinPoint; +import org.aspectj.lang.annotation.Aspect; +import org.aspectj.lang.annotation.Before; +import org.aspectj.lang.reflect.MethodSignature; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.core.annotation.Order; +import org.springframework.stereotype.Component; + +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import java.util.stream.Collectors; + +/** + * 每次请求,过滤Api中配置的权限key出来,并且判断是否具有该功能权限 + * @Author wxz + * @Description + * @Date 2020/4/23 16:16 + **/ +@Aspect +@Component +@Order(10) +public class RequirePermissionAspect { + + private static final Logger log = LoggerFactory.getLogger(RequirePermissionAspect.class); + + @Autowired + private CommonGovAccessFeignClient govAccessFeignClient; + + @Autowired + private LoginUserUtil loginUserUtil; + + @Before("@annotation(com.epmet.commons.tools.annotation.RequirePermission)") + public void before(JoinPoint point) throws Throwable { + // 取RequirePermission注解 + MethodSignature methodSignature = (MethodSignature) point.getSignature(); + RequirePermission requirePermissionAnno = methodSignature.getMethod().getAnnotation(RequirePermission.class); + RequirePermissionEnum requirePermissionEnum = requirePermissionAnno.requirePermission(); + if (requirePermissionEnum == null) { + return; + } + + String requirePermission = requirePermissionEnum.getKey(); + + LoginUserInfoResultDTO loginUserInfo = getLoginUserInfo(); + + Set ownPermissions = getPermissions(loginUserInfo.getRoleIdList()); + + // 校验操作权限 + validateOpePermission(ownPermissions, requirePermission); + + // 操作权限校验通过。将该操作key放入ThreadLocal,供DataFilterAspect中数据权限过滤器进一步使用 + ThreadLocalConstant.requirePermissionTl.set(requirePermission); + ThreadLocalConstant.loginUserInfoTl.set(loginUserInfo); + } + + /** + * 获取登陆用户信息 + * @return + */ + private LoginUserInfoResultDTO getLoginUserInfo() { + LoginUserInfoFormDTO loginUserinfoFormDTO = new LoginUserInfoFormDTO(); + loginUserinfoFormDTO.setApp(loginUserUtil.getLoginUserApp()); + loginUserinfoFormDTO.setClient(loginUserUtil.getLoginUserClient()); + loginUserinfoFormDTO.setStaffId(loginUserUtil.getLoginUserId()); + Result result = govAccessFeignClient.getLoginUserInfo(loginUserinfoFormDTO); + + if (result.getCode() != 0) { + // 查询不到权限,记录日志,抛出8000异常 + log.error("调用Access查询权限失败:{}", result.getMsg()); + throw new RenException(EpmetErrorCode.SERVER_ERROR.getCode()); + } + + LoginUserInfoResultDTO loginUserInfo = result.getData(); + if (loginUserInfo == null) { + log.error("操作权限不足,查询不到登录用户信息"); + throw new RenException(EpmetErrorCode.REQUIRE_PERMISSION.getCode()); + } + + return loginUserInfo; + } + + /** + * 校验操作权限 + */ + private void validateOpePermission(Set permissions, String reqiurePermission) { + if (!permissions.contains(reqiurePermission)) { + // 权限不足 + log.error("操作权限不足"); + throw new RenException(EpmetErrorCode.REQUIRE_PERMISSION.getCode()); + } + } + + private Set getPermissions(Set roleIdList) { + Set permissions = new HashSet<>(); + roleIdList.forEach(role -> { + // 找出该角色的所有功能操作列表 + Result> result = govAccessFeignClient.listRoleAllOperationScopesByRoleId(role); + if (!result.success()) { + // 获取operation异常 + log.error("调用GovAccess,根据RoleId查询Operation列表失败:{}", result.getMsg()); + throw new RenException(EpmetErrorCode.SERVER_ERROR.getCode()); + } + List roleOperations = result.getData(); + permissions.addAll(roleOperations.stream().map(ope -> ope.getOperationKey()).collect(Collectors.toSet())); + }); + return permissions; + } +} diff --git a/epmet-commons/epmet-commons-mybatis/src/main/java/com/epmet/commons/mybatis/aspect/ThreadLocalPreCleanAspect.java b/epmet-commons/epmet-commons-tools/src/main/java/com/epmet/commons/tools/aspect/ThreadLocalInitAspect.java similarity index 67% rename from epmet-commons/epmet-commons-mybatis/src/main/java/com/epmet/commons/mybatis/aspect/ThreadLocalPreCleanAspect.java rename to epmet-commons/epmet-commons-tools/src/main/java/com/epmet/commons/tools/aspect/ThreadLocalInitAspect.java index 532283a355..bd59b29094 100644 --- a/epmet-commons/epmet-commons-mybatis/src/main/java/com/epmet/commons/mybatis/aspect/ThreadLocalPreCleanAspect.java +++ b/epmet-commons/epmet-commons-tools/src/main/java/com/epmet/commons/tools/aspect/ThreadLocalInitAspect.java @@ -6,14 +6,17 @@ * 版权所有,侵权必究! */ -package com.epmet.commons.mybatis.aspect; +package com.epmet.commons.tools.aspect; +import com.epmet.commons.tools.constant.ThreadLocalConstant; +import com.epmet.commons.tools.dto.form.LoginUserInfoResultDTO; import com.epmet.commons.tools.exception.ExceptionUtils; import org.aspectj.lang.JoinPoint; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Before; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.springframework.core.annotation.Order; import org.springframework.stereotype.Component; /** @@ -24,15 +27,18 @@ import org.springframework.stereotype.Component; **/ @Aspect @Component -public class ThreadLocalPreCleanAspect { +@Order(0) +public class ThreadLocalInitAspect { - private static final Logger log = LoggerFactory.getLogger(ThreadLocalPreCleanAspect.class); + private static final Logger log = LoggerFactory.getLogger(ThreadLocalInitAspect.class); @Before(value = "execution(* com.epmet.controller.*Controller*.*(..)) ") public void before(JoinPoint point) throws Throwable { // 清理权限过滤中的变量残留 try { - DataFilterAspect.sqlFilter.remove(); + ThreadLocalConstant.sqlFilter.remove(); + ThreadLocalConstant.requirePermissionTl.remove(); + ThreadLocalConstant.loginUserInfoTl.remove(); } catch (Exception e) { log.error("清理sqlFilter缓存失败:{}", ExceptionUtils.getErrorStackTrace(e)); } diff --git a/epmet-commons/epmet-commons-tools/src/main/java/com/epmet/commons/tools/constant/ThreadLocalConstant.java b/epmet-commons/epmet-commons-tools/src/main/java/com/epmet/commons/tools/constant/ThreadLocalConstant.java new file mode 100644 index 0000000000..16f8113cf7 --- /dev/null +++ b/epmet-commons/epmet-commons-tools/src/main/java/com/epmet/commons/tools/constant/ThreadLocalConstant.java @@ -0,0 +1,24 @@ +package com.epmet.commons.tools.constant; + +import com.epmet.commons.tools.dto.form.LoginUserInfoResultDTO; + +/** + * ThreadLocal常亮 + */ +public class ThreadLocalConstant { + + /** + * 存储所需操作权限的 ThreadLocal + */ + public static final ThreadLocal requirePermissionTl = new ThreadLocal<>(); + + /** + * 登陆用户信息的 ThreadLocal + */ + public static final ThreadLocal loginUserInfoTl = new ThreadLocal<>(); + + /** + * 用于向DataFilterInterceptor传递权限过滤的sql片段(需要在Controller相关的AOP中进行清理,防止变量残留) + */ + public static final ThreadLocal sqlFilter = new ThreadLocal(); +} diff --git a/epmet-commons/epmet-commons-tools/src/main/java/com/epmet/commons/tools/dto/form/LoginUserInfoFormDTO.java b/epmet-commons/epmet-commons-tools/src/main/java/com/epmet/commons/tools/dto/form/LoginUserInfoFormDTO.java new file mode 100644 index 0000000000..70c418fc06 --- /dev/null +++ b/epmet-commons/epmet-commons-tools/src/main/java/com/epmet/commons/tools/dto/form/LoginUserInfoFormDTO.java @@ -0,0 +1,59 @@ +package com.epmet.commons.tools.dto.form; + +import lombok.Data; + +import javax.validation.constraints.NotBlank; +import java.util.Set; + +@Data +public class LoginUserInfoFormDTO { + + /** + * 更新权限缓存分组 + */ + public interface UpdatePermissionCache {} + + /** + * 查询当前权限列表 + */ + public interface GetStaffCurrPermissions {} + + /** + * 工作人员 id + */ + @NotBlank(message = "工作人员ID不能为空", groups = {UpdatePermissionCache.class, GetStaffCurrPermissions.class}) + private String staffId; + + /** + * 登录头信息app + */ + @NotBlank(message = "登录头信息app不能为空", groups = {UpdatePermissionCache.class, GetStaffCurrPermissions.class}) + private String app; + + /** + * 登录头信息client + */ + @NotBlank(message = "登录头信息client不能为空", groups = {UpdatePermissionCache.class, GetStaffCurrPermissions.class}) + private String client; + + /** + * 组织ID路径 + */ + private String orgIdPath; + + /** + * 权限列表 + */ + private Set permissions; + + /** + * 角色列表 + */ + private Set roleIdList; + + /** + * 当前所在网格id + */ + private String gridId; + +} diff --git a/epmet-commons/epmet-commons-mybatis/src/main/java/com/epmet/commons/mybatis/dto/form/LoginUserInfoResultDTO.java b/epmet-commons/epmet-commons-tools/src/main/java/com/epmet/commons/tools/dto/form/LoginUserInfoResultDTO.java similarity index 83% rename from epmet-commons/epmet-commons-mybatis/src/main/java/com/epmet/commons/mybatis/dto/form/LoginUserInfoResultDTO.java rename to epmet-commons/epmet-commons-tools/src/main/java/com/epmet/commons/tools/dto/form/LoginUserInfoResultDTO.java index dc7cf8e657..a249bc519a 100644 --- a/epmet-commons/epmet-commons-mybatis/src/main/java/com/epmet/commons/mybatis/dto/form/LoginUserInfoResultDTO.java +++ b/epmet-commons/epmet-commons-tools/src/main/java/com/epmet/commons/tools/dto/form/LoginUserInfoResultDTO.java @@ -1,4 +1,4 @@ -package com.epmet.commons.mybatis.dto.form; +package com.epmet.commons.tools.dto.form; import lombok.Data; @@ -7,6 +7,11 @@ import java.util.Set; @Data public class LoginUserInfoResultDTO { + /** + * 用户ID + */ + private String userId; + /** * 权限列表 */ diff --git a/epmet-commons/epmet-commons-tools/src/main/java/com/epmet/commons/tools/dto/form/RoleOpeScopeResultDTO.java b/epmet-commons/epmet-commons-tools/src/main/java/com/epmet/commons/tools/dto/form/RoleOpeScopeResultDTO.java new file mode 100644 index 0000000000..41cda81c75 --- /dev/null +++ b/epmet-commons/epmet-commons-tools/src/main/java/com/epmet/commons/tools/dto/form/RoleOpeScopeResultDTO.java @@ -0,0 +1,33 @@ +package com.epmet.commons.tools.dto.form; + +import lombok.Data; + +@Data +public class RoleOpeScopeResultDTO { + + /** + * 角色ID + */ + private String roleId; + + /** + * 操作key + */ + private String operationKey; + + /** + * 范围key + */ + private String scopeKey; + + /** + * 范围名称 + */ + private String scopeName; + + /** + * 范围序号 + */ + private String scopeIndex; + +} diff --git a/epmet-commons/epmet-commons-tools/src/main/java/com/epmet/commons/tools/exception/EpmetErrorCode.java b/epmet-commons/epmet-commons-tools/src/main/java/com/epmet/commons/tools/exception/EpmetErrorCode.java index 2cb2859bde..8aa19240ca 100644 --- a/epmet-commons/epmet-commons-tools/src/main/java/com/epmet/commons/tools/exception/EpmetErrorCode.java +++ b/epmet-commons/epmet-commons-tools/src/main/java/com/epmet/commons/tools/exception/EpmetErrorCode.java @@ -34,7 +34,7 @@ public enum EpmetErrorCode { NOT_DEL_AGENCY_PER(8205, "该机关存在工作人员,不允许删除"), NOT_DEL_DEPARTMENT(8206, "该部门存在工作人员,不允许删除"), - REQUIRE_PERMISSION(8301, "没有足够的操作权限"), + REQUIRE_PERMISSION(8301, "您没有足够的操作权限"), NOT_ADD_GRID(8401,"您当前的网格名称已存在,请重新修改"), MOBILE_USED(8402,"该手机号已注册"), diff --git a/epmet-commons/epmet-commons-tools/src/main/java/com/epmet/commons/tools/exception/RenExceptionHandler.java b/epmet-commons/epmet-commons-tools/src/main/java/com/epmet/commons/tools/exception/RenExceptionHandler.java index b7d8fb03ec..34703ba3a8 100644 --- a/epmet-commons/epmet-commons-tools/src/main/java/com/epmet/commons/tools/exception/RenExceptionHandler.java +++ b/epmet-commons/epmet-commons-tools/src/main/java/com/epmet/commons/tools/exception/RenExceptionHandler.java @@ -55,6 +55,11 @@ public class RenExceptionHandler { @ExceptionHandler(RenException.class) public Result handleRRException(RenException ex){ logger.error(ExceptionUtils.getErrorStackTrace(ex)); + if (ex.getCode() > 8000) { + Result result=new Result().error(ex.getCode()); + result.setData(ex.getMsg()); + return result; + } Result result=new Result().error(); result.setData(ex.getMsg()); return result; diff --git a/epmet-commons/epmet-commons-tools/src/main/java/com/epmet/commons/tools/feign/CommonGovAccessFeignClient.java b/epmet-commons/epmet-commons-tools/src/main/java/com/epmet/commons/tools/feign/CommonGovAccessFeignClient.java new file mode 100644 index 0000000000..682a30e96c --- /dev/null +++ b/epmet-commons/epmet-commons-tools/src/main/java/com/epmet/commons/tools/feign/CommonGovAccessFeignClient.java @@ -0,0 +1,37 @@ +package com.epmet.commons.tools.feign; + +import com.epmet.commons.tools.constant.ServiceConstant; +import com.epmet.commons.tools.dto.form.LoginUserInfoFormDTO; +import com.epmet.commons.tools.dto.form.LoginUserInfoResultDTO; +import com.epmet.commons.tools.dto.form.RoleOpeScopeResultDTO; +import com.epmet.commons.tools.feign.fallback.CommonGovAccessFeignClientFallback; +import com.epmet.commons.tools.utils.Result; +import org.springframework.cloud.openfeign.FeignClient; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; + +import java.util.List; + +/** + * @Description + * @Author sun + */ +//, url = "localhost:8099" +@FeignClient(name = ServiceConstant.GOV_ACCESS_SERVER, fallback = CommonGovAccessFeignClientFallback.class) +public interface CommonGovAccessFeignClient { + + /** + * 查询登陆用户信息 + * @return + */ + @PostMapping("/gov/access/access/loginuserinfo") + Result getLoginUserInfo(@RequestBody LoginUserInfoFormDTO dto); + + /** + * 查询角色所有operation及其范围(缓存) + * @return + */ + @PostMapping("/gov/access/access/roleallopesandscopes/{roleId}") + Result> listRoleAllOperationScopesByRoleId(@PathVariable("roleId") String roleId); +} diff --git a/epmet-commons/epmet-commons-tools/src/main/java/com/epmet/commons/tools/feign/fallback/CommonGovAccessFeignClientFallback.java b/epmet-commons/epmet-commons-tools/src/main/java/com/epmet/commons/tools/feign/fallback/CommonGovAccessFeignClientFallback.java new file mode 100644 index 0000000000..a03f87ccc9 --- /dev/null +++ b/epmet-commons/epmet-commons-tools/src/main/java/com/epmet/commons/tools/feign/fallback/CommonGovAccessFeignClientFallback.java @@ -0,0 +1,33 @@ +package com.epmet.commons.tools.feign.fallback; + +import com.epmet.commons.tools.constant.ServiceConstant; +import com.epmet.commons.tools.dto.form.LoginUserInfoFormDTO; +import com.epmet.commons.tools.dto.form.LoginUserInfoResultDTO; +import com.epmet.commons.tools.dto.form.RoleOpeScopeResultDTO; +import com.epmet.commons.tools.feign.CommonGovAccessFeignClient; +import com.epmet.commons.tools.utils.ModuleUtils; +import com.epmet.commons.tools.utils.Result; +import org.springframework.stereotype.Component; +import org.springframework.web.bind.annotation.PathVariable; + +import java.util.List; + +/** + * 调用政府端权限 + * @Author wxz + * @Description + * @Date 2020/4/24 11:17 + **/ +@Component +public class CommonGovAccessFeignClientFallback implements CommonGovAccessFeignClient { + + @Override + public Result getLoginUserInfo(LoginUserInfoFormDTO dto) { + return ModuleUtils.feignConError(ServiceConstant.GOV_ACCESS_SERVER, "getLoginUserInfo", dto); + } + + @Override + public Result> listRoleAllOperationScopesByRoleId(@PathVariable("roleId") String roleId){ + return ModuleUtils.feignConError(ServiceConstant.GOV_ACCESS_SERVER, "listRoleAllOperationScopesByRoleId", roleId); + } +} diff --git a/epmet-module/gov-access/gov-access-client/src/main/java/com/epmet/dto/result/LoginUserInfoResultDTO.java b/epmet-module/gov-access/gov-access-client/src/main/java/com/epmet/dto/result/LoginUserInfoResultDTO.java index ee62b2d80e..440e5eb307 100644 --- a/epmet-module/gov-access/gov-access-client/src/main/java/com/epmet/dto/result/LoginUserInfoResultDTO.java +++ b/epmet-module/gov-access/gov-access-client/src/main/java/com/epmet/dto/result/LoginUserInfoResultDTO.java @@ -7,6 +7,11 @@ import java.util.Set; @Data public class LoginUserInfoResultDTO { + /** + * 用户ID + */ + private String userId; + /** * 权限列表 */ diff --git a/epmet-module/gov-access/gov-access-server/src/main/java/com/epmet/controller/AccessController.java b/epmet-module/gov-access/gov-access-server/src/main/java/com/epmet/controller/AccessController.java index 775496d0a8..caabc26491 100644 --- a/epmet-module/gov-access/gov-access-server/src/main/java/com/epmet/controller/AccessController.java +++ b/epmet-module/gov-access/gov-access-server/src/main/java/com/epmet/controller/AccessController.java @@ -64,6 +64,7 @@ public class AccessController { resultDTO.setOrgIdPath(govTokenDto.getOrgIdPath()); resultDTO.setGridIdList(govTokenDto.getGridIdList()); resultDTO.setDeptIdList(govTokenDto.getDeptIdList()); + resultDTO.setUserId(govTokenDto.getUserId()); } return new Result().ok(resultDTO); }