如何实现一个权限管理系统?

如何实现一个权限管理系统?系统安全一直是在系统开发中不可规避的问题 而权限控制又跟系统安全密不可分 大到用户的访问 小到一个页面的按钮 都有可能涉及到权限的控制 而 renren security 便给我们提供了一套权限系统开发的解决方案

一、序言

系统安全一直是在系统开发中不可规避的问题,而权限控制又跟系统安全密不可分,大到用户的访问,小到一个页面的按钮,都有可能涉及到权限的控制。而renren-security便给我们提供了一套权限系统开发的解决方案。

renren-security是”人人社区”社区开源的轻量级权限管理系统。系统采用SprinBoot、Mybatis、Shiro框架进行开发,极低门槛,拿来即用,支持分布式部署、Quartz分布式集群调度、部门管理、数据权限、云存储等功能。

二、项目特点

三、系统设计

系统结构的设计也比较清晰,由admin、api、common等几个模块组成,每个模块实现的功能大体如下:

common:公共模块,以jar包的形式被其他模块所依赖。实现了一些工具类和公共功能。包含时间处理、分页、Sql过滤、Xss过滤和Redis切面定义、自定义异常处理等功能。

admin:管理系统模块,以war包形式独立部署。基于前后端分离的思想,主要用来用来开发后台管理系统。包含用户管理、角色管理、部门管理、菜单管理、定时任务、文件上传、API校验,同时采用Redis进行数据缓存,支持单机和集群的部署。

用户登录时对用户的账号密码进行验证,获取用户的信息和role权限,页面显示的时候会根据用户拥有的权限显示对应的状态,接口请求的时候也会进行用户权限的校验,数据保存到数据库时候还进行Sql和Xss的过滤,整个过程的核心思路是Shiro对用户的认证和授权。具体流程如下图:如何实现一个权限管理系统?

四、权限管理

实现Shiro的认证和授权,需要自定义Realm继承于AuthorizingRealm,同时重写doGetAuthenticationInfo(认证)和doGetAuthorizationInfo(授权)这两个方法。这里对于系统与Shiro的整合就不再做多的说明。

用户登录的时候,将用户的账号和密码包装成一个UsernamePasswordToken后,再调用login提交账户认证,shiro会自动调用我们重写的doGetAuthenticationInfo方法。

Subject subject = SecurityUtils.getSubject(); UsernamePasswordToken token = new UsernamePasswordToken(username, password); //提交认证 subject.login(token); 
//Shiro进行认证 @Override protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authcToken) throws AuthenticationException { UsernamePasswordToken token = (UsernamePasswordToken)authcToken; //获取用户信息 SysUserEntity user = new SysUserEntity(); user.setUsername(token.getUsername()); user = sysUserDao.selectOne(user); //账号不存在 if(user == null) { throw new UnknownAccountException("账号或密码不正确"); } SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(user, user.getPassword(), ByteSource.Util.bytes(user.getSalt()), getName()); return info; } 

如果认证成功,那么在系统的任何地方通过SecurityUtils.getSubject()方法就可以获取认证通过的信息。我们也可以借助它的这点特性,实现用户的自动登录。

这里需要补充一点,系统把权限化成了一个个的标签保存在数据库中,用户的权限中持有对应的标签则表示拥有对应的操作权限。而对于Shiro的授权,在doGetAuthorizationInfo中需要获取用户的所有权限列表,通过权限列表筛选出是否拥有操作权限。

//Shiro进行授权 @Override protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) { //获取认证时候添加到SimpleAuthenticationInfo中的实例 SysUserEntity user = (SysUserEntity)principals.getPrimaryPrincipal(); Long userId = user.getUserId(); //查询用户所有权限 Set 
  
    permsSet = new HashSet 
   
     (); List 
    
      permsList = sysUserDao.queryAllPerms(userId); for(String perms : permsList){ if(StringUtils.isBlank(perms)){ continue; } permsSet.addAll(Arrays.asList(perms.trim().split(","))); } SimpleAuthorizationInfo info = new SimpleAuthorizationInfo(); info.setStringPermissions(permsSet); return info; } 
     
    
  

Shiro的授权是被动的,只有被相应的条件触发才会进行用户授权,方式有以下几种:

1.作用于页面。页面里如果遇到<#if shiro.hasPermission(“sys:del”)>
,Shiro会调用自定义Realm获取权限信息,看”sys:del”是否在权限数据中存在,存在则授权通过,不存在则拒绝访问,可应用于对一些按钮和标签的特定开放。

<#if shiro.hasPermission("sys:add")> 新增 
   <#if shiro.hasPermission("sys:del")> 删除 
   

2.通过注解的方式作用于接口。在controller中,方法如果加了@RequiresPermissions(“sys:del”)注解,Shiro同样会调用自定义Realm获取权限信息,看”sys:del”是否在权限数据中存在,存在则授权通过,不存在则拒绝访问,从而实现对接口的权限校验。

@RequestMapping("/delete") @RequiresPermissions("sys:del") public R delete(long deptId){ //判断是否有子部门 List 
  
    deptList = sysDeptService.queryDetpIdList(deptId); if(deptList.size() > 0){ return R.error("请先删除子部门"); } sysDeptService.deleteById(deptId); return R.ok(); } 
  

五、总结

到此,基本上便实现了Shiro在页面和接口的权限控制。当然,Shiro更多是作用于表现层的一个控制,而出于系统安全考虑也应该增加对数据的校验。因此在数据层面,则可通过Sql过滤和Xss过滤的方式实现过滤。项目中已经为其封装成工具,原理都是正则匹配和字符串替换,感兴趣的伙伴可以直接到项目里查看,这里就不再累述了。

系统除了实现权限控制外,也实现了很多后台管理系统开发中常用到的一些功能,像Quartz分布式集群调度、多数据源动态切换以及集群部署下Session管理,感兴趣的伙伴也可以查看源码。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/220073.html原文链接:https://javaforall.net

(0)
上一篇 2026年3月17日 下午9:18
下一篇 2026年3月17日 下午9:19


相关推荐

  • oracle 截取字符串最后几位

    oracle 截取字符串最后几位selectsubstr 12345 greatest 位数 length 12345 位数 fromdual nbsp ps 位数是数字

    2026年3月17日
    3
  • 水力发电属于可再生能源吗_薪柴属于可再生能源吗

    水力发电属于可再生能源吗_薪柴属于可再生能源吗电属于二次能源,谈不上可再生、不可再生。二次能源二次能源是指由一次能源经过加工转换以后得到的能源,包括电能、汽油、柴油、液化石油气,氢能等。二次能源又可以分为“过程性能源”和

    2022年8月2日
    12
  • linux 中查看组成员命令,linux 用户和用户组命令

    linux 中查看组成员命令,linux 用户和用户组命令1 用户命令 1 1 新增用户 useradd 选项用户名参数说明 选项 ccomment 指定一段注释性描述 d 目录指定用户主目录 如果此目录不存在 则同时使用 m 选项 可以创建主目录 g 用户组指定用户所属的用户组 G 用户组 用户组指定用户所属的附加组 sShell 文件指定用户的登录 Shell u 用户号指定用户的用户号 如果同时有 o 选项 则可以重复使用其他用户的标

    2026年3月26日
    2
  • python 数组基本操作

    python 数组基本操作Python 没有数组概念 使用列表 list 来实现的 罗列几个基本操作 声明一维 demo 动态大小数组 成员数可变 demo 3 静态大小数组 三个成员 标号从 0 开始 demo a b 数组初值二维 demo 3 demo 3 4 增加成员 demo 声明动态数组 demo append a 增加一个成员清空 demo a b demo clear 拷贝 Python 中的数组虽然是可变变

    2026年3月18日
    2
  • 基于遗传算法的函数极值求取_遗传算法计算二元函数最大值

    基于遗传算法的函数极值求取_遗传算法计算二元函数最大值前面在《遗传算法通识》中介绍了基本原理,这里结合实例,看看遗传算法是怎样解决实际问题的。有一个函数:f(x)=x+10sin5x+7cos4xf(x)=x+10\sin5x+7\cos4x求其在区间[-10,10]之间的最大值。下面是该函数的图像:在本例中,我们可以把x作为个体的染色体,函数值f(x)作为其适应度值,适应度越大,个体越优秀,最大的适应度就是我们要求的最大值。

    2025年11月7日
    6
  • 计算机的储存容量1kb等于多少byte,1M等于多少字节?

    计算机的储存容量1kb等于多少byte,1M等于多少字节?1M等于多少字节?以下文字资料是由(历史新知网www.lishixinzhi.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!1M等于多少字节?不是1M等于多少字节,是1MB等于多少字节。字节(Byte/bait/n.[C])是计算机信息技术用于计量存储容量的一种计量单位,也表示一些计算机编程语言中的数据类型和语言字符。字节用符号“B”表示。MB(全称MByte):计算机中…

    2022年5月9日
    83

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号