# auth-it **Repository Path**: pifutan/auth-it ## Basic Information - **Project Name**: auth-it - **Description**: 框架项目,数据权限+功能权限 - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2022-07-16 - **Last Updated**: 2025-03-31 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # 权限框架 介绍:支持功能权限和数据权限,并支持扩展,前端组件待开发 # 已支持功能 可以指定属性维度结合用户属性去查询资源列表 超级管理员拥有所有权限 授权问题:唯一性使用on duplicate key或者insert ignore into,可支持配置 角色的各种使用方式:针对方法进行限制、作为一个维度、权限表达式 通用高级查询 上下文数据信息,默认使用懒加载的方式,即需要时才去查询,但是需要应用做好缓存,以提高性能 # 未支持功能 根据租户分库,根据资源目录分表(未完善) 查询问题:需要支持查询资源扩展表,支持简单自定义关键字查询,支持高级查询,支持任意字段排序 授权用户能够查看整个资源目录下的资源 授权用户能够查看指定资源目录下指定属性的资源(多属性且关系) 支持向上继承权限,向下授权访问 自动创建授权关系表,如user_role 针对第三方系统,权限机制的扩展,可以有限地由第三方决定权限 # 用户手册 ## 一、集成到项目中(必备动作) 1、引入jar包 ``` com.pifutan.authit auth-it-framework ${auth-it-version} com.pifutan.authit auth-it-core ${auth-it-version} ``` 2、在Application启动类上添加注解 @EnableAuthIt 或 @EnableAuthItImpl 3、继承AuthContextServiceImpl实现自己的AppAuthContextServiceImpl 4、需要在登录拦截中调用 authContextService.initAuthContext 方法进行权限上下文的初始化,或者确保在调用权限相关功能之前进行初始化, 并在合适的时候调用UserContext.remove(),一定要调用否则时间久了可能内存溢出 5、针对资源,想要自定义资源编码的可以用@ResCode注解标注(会用来做授权的主键和关联查询的外键) 6、继承AbstractUserAttribute定义UserAttribute实现自己支持的用户属性,且在AppAuthContextServiceImpl中实现查询。 如果你的应用中已定义登录用户如PiUser,可直接使用,再AppAuthContextServiceImpl中定义获取方式(如RequestHolder中取出) 7、需要使用AuthItPaginationInnerInterceptor分页插件,否则部分count语句不支持,高级查询也将不支持。 @EnableAuthIt会引入,如果项目中自定义了MybatisPlusInterceptor,则需要添加 ``` interceptor.addInnerInterceptor(new AuthItPaginationInnerInterceptor(DbType.MYSQL)); ``` 8、如果项目中已经有@ControllerAdvice注解,可添加一下AuthItException处理 ``` @ExceptionHandler(AuthItException.class) public ResultT handleThrowable(AuthItException e, HttpServletRequest request, HttpServletResponse response) { return ResultT.error(e.getCode(), e.getMessage()); } ``` 注意点: 1、尽量少地使用AuthContext而是使用UserContext 2、需要注意继承了BaseAuthMapper的mapper是否有重名的接口方法,需要区分开来 3、新版springboot可能需要添加spring.main.allow-circular-references=true ## 二、使用功能权限 1、在类或者方法上添加注解 @AuthIt 1.1 支持按角色控制权限 1.2 支持权限表达式,支持用户属性ua和方法传参 ``` 如:#ua.attribute.level > 1 如:#ua.attribute.level > 1 and #resDirCode == 'resDir' 如:#ua.roleCode.contains(#resDirCode + 'Admin') ``` 1.3 支持自定义权限拦截,自定义resolver具有优先性,添加@Component实现AbstractAuthItFilter即可 ## 使用数据权限 1、基础mapper继承AuthBaseMapper,如: ``` @Component public interface AuthResMapper extends AuthBaseMapper { } ``` 2、serviceImpl继承QueryResImpl,可参照auth-it-test中的com.pifutan.authit.test.service.QueryAuthRes 3、构造查询策略,当然在此之前需要注意授权的生成。可参照com.pifutan.authit.test.service.QueryAuthRes的一些权限策略构造 ``` @Service public class QueryAuthRes extends QueryResImpl implements QueryRes { public static AuthStrategies userStrategy() { return new AuthStrategies(new AuthStrategy(AuthResUser.class)); } public static AuthStrategies roleStrategy() { return new AuthStrategies(new AuthStrategy(AuthResRole.class)); } public static AuthStrategies userAndRoleStrategy() { return new AuthStrategies(new AuthStrategy(AuthResUser.class), new AuthStrategy(AuthResRole.class)); } public static AuthStrategies userAndGroupStrategy() { return new AuthStrategies(new AuthStrategy(AuthResUser.class), new AuthStrategy(AuthResGroup.class)); } /** * AuthParentCompany * CanViewChild * 授权给父级公司,即上级公司可查看下级公司数据 * 资源数据在存储的时候需要存储公司链条,字段名指定为company_code_chain,存储值如:[child, parent, grandparent] * 查询时使用like 用户companyCode,如:company_code_chain like %child%' * * @return */ public static AuthStrategies canViewChildCompanyStrategy() { return new AuthStrategies(new AuthStrategy(ResExtendCompany.class.getSimpleName(), AuthParam.authParentCompany())); } /** * AuthChildCompany * CanViewParent * 授权给下级公司,即子公司可查看父级公司数据 * 资源数据在存储的时候只需要存储当前所属公司,字段名指定为company_code * 但是查询时使用公司链条,如:company_code in ('child', 'parent', 'grandparent') * * @return */ public static AuthStrategies canViewParentCompanyStrategy() { return new AuthStrategies(new AuthStrategy(ResExtendCompany.class.getSimpleName(), AuthParam.authChildCompany())); } /** * 可查看下级公司,即授权给上级 * * @param keyword * @return */ public List> resExtendListCanViewChildCompany(String keyword) { ExtendQueryParam extendQueryParam = new ExtendQueryParam(); extendQueryParam.setTableName(StringUtils.camelToUnderline(ResExtendCompany.class.getSimpleName())); extendQueryParam.setIsOr(false); if (StringUtils.isNotBlank(keyword)) { extendQueryParam.addOrQueryParam(new QueryParam("res_name", QueryParam.LIKE, keyword)); } List extendQueryParamList = Arrays.asList(extendQueryParam); List extendMultiQueryParamList = null; String orderBySql = null; return resExtendList(canViewChildCompanyStrategy(), extendQueryParamList, extendMultiQueryParamList, orderBySql); } /** * 可查看上级公司,即授权给下级 * * @param keyword * @return */ public List> resExtendListCanViewParentCompany(String keyword) { ExtendQueryParam extendQueryParam = new ExtendQueryParam(); extendQueryParam.setTableName(StringUtils.camelToUnderline(ResExtendCompany.class.getSimpleName())); extendQueryParam.setIsOr(false); if (StringUtils.isNotBlank(keyword)) { extendQueryParam.addOrQueryParam(new QueryParam("res_name", QueryParam.LIKE, keyword)); } List extendQueryParamList = Arrays.asList(extendQueryParam); List extendMultiQueryParamList = null; String orderBySql = null; return resExtendList(canViewParentCompanyStrategy(), extendQueryParamList, extendMultiQueryParamList, orderBySql); } } ``` 4、使用权限策略进行查询,如果已经在service中封装了则使用如上面的resExtendListCanViewChildCompany等方法,基础使用可参照com.pifutan.authit.test.controller.TestQueryController 如: ``` @Autowired QueryAuthRes queryAuthRes; @Autowired AuthContextService authContextService; private LambdaQueryWrapper keywordWrapper(String keyword) { // TODO: 2021-09-30 默认关键字查询 return Wrappers.lambdaQuery() .and(keyword != null && !keyword.trim().isEmpty(), wrap各项目销售运营部对接人员体专补贴(新建店,保店,直营店,加盟店)-刘汝玲 13392603800高租金门店补贴对接-刘汝玲 13392603800KA对投返利相关数据发起&提交-吴玲琪 13690024912堡垒店补贴返利流程-刘汝玲 13392603800临促/枪手、路演申请&核销流程-张月薇 13660183031端对端产品侧流程申请及核销-张月薇 13660183031高空户外大牌/门头补贴-吴玲琪 13690024912抢滩行动审批核销流程-吴玲琪 13690024912per -> wrapper.like(AuthRes::getResName, keyword).or().like(AuthRes::getOfficeCity, keyword)) .orderByDesc(AuthRes::getCreateTime, AuthRes::getId); } @GetMapping("list/byRole") public List listByRole(String keyword) { return queryAuthRes.resList(QueryAuthRes.roleStrategy(), keywordWrapper(keyword)); } ``` 5、使用动态策略的话,建议继承DynamicAuthStrategyGroupServiceImpl实现自己的AppDynamicAuthStrategyGroupServiceImpl进行一些缓存