Guns权限管理系统实战:基于Shiro的数据权限控制终极方案
【免费下载链接】gunsGuns基于SpringBoot,致力于做更简洁的后台管理系统,完美整合springmvc + shiro + 分页插件PageHelper + 通用Mapper + beetl!Guns项目代码简洁,注释丰富,上手容易,同时Guns包含许多基础模块(用户管理,角色管理,部门管理,字典管理等10个模块),可以直接作为一个后台管理系统的脚手架.项目地址: https://gitcode.com/gh_mirrors/gun/guns
Guns权限管理系统是基于SpringBoot的后台管理系统框架,它完美整合了Spring MVC + Shiro + PageHelper + 通用Mapper + Beetl等技术栈。对于企业级应用开发而言,数据权限控制是权限管理系统的核心功能,Guns通过独创的MyBatis数据范围拦截器实现了简洁高效的数据权限控制方案。🚀
什么是数据权限控制?
数据权限控制是指对拥有相同角色的用户,根据其所属部门的不同进行相应的数据筛选。例如,两个角色都有用户管理权限,但下级部门的用户不能看到上级部门的数据。Guns的数据权限控制以部门ID为单位来标识,实现了灵活的数据隔离机制。
Guns权限管理系统架构解析
1. Shiro权限认证框架整合
Guns通过ShiroConfig.java完美整合Apache Shiro框架,实现了完整的认证和授权体系:
@Bean public ShiroFilterFactoryBean shiroFilter(DefaultWebSecurityManager securityManager) { ShiroFilterFactoryBean shiroFilter = new ShiroFilterFactoryBean(); shiroFilter.setSecurityManager(securityManager); shiroFilter.setLoginUrl("/login"); shiroFilter.setSuccessUrl("/"); shiroFilter.setUnauthorizedUrl("/global/error"); Map<String, String> hashMap = new LinkedHashMap<>(); hashMap.put("/static/**", "anon"); hashMap.put("/login", "anon"); hashMap.put("/global/sessionError", "anon"); hashMap.put("/kaptcha", "anon"); hashMap.put("/**", "user"); shiroFilter.setFilterChainDefinitionMap(hashMap); return shiroFilter; }2. 独创的数据范围拦截器
Guns的核心创新在于DataScopeInterceptor.java,这是一个MyBatis拦截器,实现了数据权限的自动过滤:
@Intercepts({@Signature(type = StatementHandler.class, method = "prepare", args = {Connection.class, Integer.class})}) public class DataScopeInterceptor implements Interceptor { public Object intercept(Invocation invocation) throws Throwable { // 查找参数中包含DataScope类型的参数 DataScope dataScope = findDataScopeObject(parameterObject); if (dataScope != null) { String scopeName = dataScope.getScopeName(); List<Integer> deptIds = dataScope.getDeptIds(); String join = CollectionKit.join(deptIds, ","); originalSql = "select * from (" + originalSql + ") temp_data_scope where temp_data_scope." + scopeName + " in (" + join + ")"; metaStatementHandler.setValue("delegate.boundSql.sql", originalSql); } return invocation.proceed(); } }3. 数据权限实体类
DataScope.java定义了数据权限的核心结构:
public class DataScope { private String scopeName = "deptid"; // 限制范围的字段名称 private List<Integer> deptIds; // 限制范围的部门ID集合 public DataScope(String scopeName, List<Integer> deptIds) { this.scopeName = scopeName; this.deptIds = deptIds; } }实战:如何在业务中使用数据权限
1. 用户管理中的数据权限应用
在UserMgrController.java中,数据权限被广泛应用:
@RequestMapping("/list") @Permission @ResponseBody public Object list(@RequestParam(required = false) String name, @RequestParam(required = false) String beginTime, @RequestParam(required = false) String endTime, @RequestParam(required = false) Integer deptid) { Integer userId = ShiroKit.getUser().getId(); User user = userMapper.selectByPrimaryKey(userId); DataScope dataScope = new DataScope(ShiroKit.getDeptDataScope(user)); List<Map<String, Object>> users = userMapper.selectUsers(dataScope, name, beginTime, endTime, deptid); return new UserWarpper(users).warp(); }2. Mapper接口的数据权限参数
UserMapper.java中定义了支持数据权限的查询方法:
List<Map<String, Object>> selectUsers(@Param("dataScope") DataScope dataScope, @Param("name") String name, @Param("beginTime") String beginTime, @Param("endTime") String endTime, @Param("deptid") Integer deptid);3. 部门数据范围获取
ShiroKit.java提供了获取用户数据权限范围的方法:
public static List<Integer> getDeptDataScope(User user) { Integer deptId = user == null ? getUser().getDeptId() : user.getDeptid(); List<Integer> subDeptIds = ConstantFactory.me().getSubDeptId(deptId); subDeptIds.add(deptId); return subDeptIds; }权限注解与AOP拦截
1. 权限注解定义
Permission.java定义了权限检查注解:
@Inherited @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.METHOD}) public @interface Permission { String[] value() default {}; }2. AOP权限拦截器
PermissionAop.java实现了基于注解的权限检查:
@Aspect @Component public class PermissionAop { @Pointcut(value = "@annotation(com.stylefeng.guns.common.annotion.Permission)") private void cutPermission() {} @Around("cutPermission()") public Object doPermission(ProceedingJoinPoint point) throws Throwable { MethodSignature ms = (MethodSignature) point.getSignature(); Method method = ms.getMethod(); Permission permission = method.getAnnotation(Permission.class); Object[] permissions = permission.value(); if (permissions == null || permissions.length == 0) { // 检查全体角色 boolean result = PermissionCheckManager.checkAll(); if (result) { return point.proceed(); } else { throw new NoPermissionException(); } } else { // 检查指定角色 boolean result = PermissionCheckManager.check(permissions); if (result) { return point.proceed(); } else { throw new NoPermissionException(); } } } }权限管理界面展示
Guns提供了直观的权限管理界面,让管理员可以轻松配置角色和权限:
系统提供了完整的用户管理功能,包括用户创建、角色分配、权限设置等:
数据权限配置实战
1. 配置数据权限拦截器
在MyBatis配置中启用数据权限拦截器:
@Bean public DataScopeInterceptor dataScopeInterceptor() { return new DataScopeInterceptor(); }2. 业务层数据权限使用
在业务逻辑中,只需在Mapper方法参数中添加DataScope对象即可:
// 查询用户列表,自动应用数据权限 public List<User> findUsersByCondition(DataScope dataScope, UserQuery query) { return userMapper.selectUsers(dataScope, query.getName(), query.getBeginTime(), query.getEndTime(), query.getDeptid()); }3. 控制器层权限控制
结合权限注解实现细粒度控制:
@Permission(Const.ADMIN_NAME) // 仅管理员可访问 @RequestMapping("/add") @BussinessLog(value = "添加管理员", key = "account", dict = Dict.UserDict) @ResponseBody public Tip add(@Valid UserDto user, BindingResult result) { // 业务逻辑 }权限管理的最佳实践
1. 分层权限控制策略
Guns采用三层权限控制策略:
- URL级别权限:通过Shiro过滤器链控制
- 方法级别权限:通过@Permission注解控制
- 数据级别权限:通过DataScope拦截器控制
2. 动态数据权限
根据用户角色动态生成数据权限范围:
public DataScope buildDataScopeByUser(User user) { if (ShiroKit.isAdmin()) { // 管理员拥有所有数据权限 return null; } else { // 普通用户只能看到自己部门及子部门的数据 List<Integer> deptIds = ShiroKit.getDeptDataScope(user); return new DataScope("deptid", deptIds); } }3. 权限缓存优化
Guns利用Ehcache对权限数据进行缓存,提升系统性能:
@Cacheable(value = Cache.CONSTANT, key = "'" + CacheKey.DEPT_NAME + "'+#deptId") public String getDeptName(Integer deptId) { return this.deptMapper.getDeptName(deptId); }系统部署与配置
1. 数据库初始化
首先导入项目中的SQL文件:
- guns.sql - 系统基础数据表
- biz.sql - 业务数据表
2. 配置文件调整
修改application.yml中的数据库配置:
spring: datasource: url: jdbc:mysql://localhost:3306/guns?autoReconnect=true&useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull username: root password: 1234563. 启动项目
Guns支持多种启动方式:
- 在IDE中运行GunsApplication类的main方法
- 使用Maven打包后通过Java命令启动
- 打包为WAR文件部署到Tomcat
总结与展望
Guns权限管理系统通过创新的数据范围拦截器设计,解决了企业级应用中复杂的数据权限控制问题。其核心优势包括:
- 简洁高效:通过MyBatis拦截器实现数据权限,无需修改业务SQL
- 灵活配置:支持基于部门的数据权限控制,满足多层级组织架构需求
- 易于扩展:DataScope设计可扩展支持更多维度的数据权限控制
- 性能优秀:结合Ehcache缓存,权限验证性能优异
通过本文的详细介绍,您应该已经掌握了Guns权限管理系统的核心原理和实战应用。无论是新建项目还是现有系统改造,Guns都提供了一个成熟、稳定且易于扩展的权限管理解决方案。💪
核心关键词:Guns权限管理系统、Shiro数据权限控制、SpringBoot后台管理、数据范围拦截器、企业级权限管理
长尾关键词:基于Shiro的数据权限控制终极方案、Guns权限管理系统实战教程、SpringBoot权限管理框架、企业级后台管理系统数据隔离、MyBatis数据范围拦截器实现
【免费下载链接】gunsGuns基于SpringBoot,致力于做更简洁的后台管理系统,完美整合springmvc + shiro + 分页插件PageHelper + 通用Mapper + beetl!Guns项目代码简洁,注释丰富,上手容易,同时Guns包含许多基础模块(用户管理,角色管理,部门管理,字典管理等10个模块),可以直接作为一个后台管理系统的脚手架.项目地址: https://gitcode.com/gh_mirrors/gun/guns
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考