博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
(2)shiro角色资源权限
阅读量:5984 次
发布时间:2019-06-20

本文共 2471 字,大约阅读时间需要 8 分钟。

一般在web系统权限设计中,一般分为三个维度,用户,角色,资源,一个用户可以拥有多个角色,比如说可以是老师,也可以是班主任,一个角色也可以拥有多个资源。

比如老师同时拥有查看班级学生和批改作业的资源,如果一个用户有老师这个角色,那么就代表他拥有了查看班级学生和批改作业的两个资源权限。

因为只判断角色颗粒度太粗,而根据资源权限则比较细。

 

校验权限代码

在classpath下新建shiro-role.ini文件,内容如下:

代表有一个zhang的用户,拥有role1角色(如果有多个角色,后面用逗号继续隔开role1,role2)

role1这个角色有两个资源,分别是user:create和user:update。

[users]zhang=123456,role1[roles]role1=user:create,user:update

测试代码:

Factory
factory =new IniSecurityManagerFactory("classpath:shiro-role.ini"); //得到安全管理器 SecurityManager securityManager = factory.getInstance(); //将securityManager托管给SecurityUtils SecurityUtils.setSecurityManager(securityManager); Subject subject = SecurityUtils.getSubject(); UsernamePasswordToken token = new UsernamePasswordToken("zhang", "123456"); try { subject.login(token); } catch (AuthenticationException e) { e.printStackTrace(); } //是否已经认证 System.out.println(subject.isAuthenticated()); //校验是否有对应的权限和资源,如果没有则抛出对应的异常UnauthorizedException subject.checkRole("role1"); subject.checkPermission("user:create"); //退出 subject.logout();

过程没有遇到任何错误,执行到了最后,但是如果你check一个zhang不存在的role或者permission,则会报UnauthorizedException。

 

身份和凭证

在登陆中,用户需要提供principals(身份)和credentials(证明/凭证)提供给shiro来进行认证和授权。

principals可以有多个身份,但是只能有一个Primary principals,一般是登录账号,比如手机号。

credentials一般是密码。

在UsernamePasswordToken的账户密码就对应着身份和凭证。

 

 

subject.login()原理

当执行subject.login的时候,实际调用的是securityManager所属的Authenticator(默认是ModularRealmAuthenticator)的doAuthenticate方法进行验证。

 

 他会根据当前设置了几个realm走不同的方法(后面介绍多个realms)

 最终走的realm对应的getAuthenticationInfo方法,判断用户账号密码是否正确,如果错误则抛出对应的异常。正确则返回一个AuthenticationInfo对象。(这里是SimpleAuthenticationInfo)

 所以后面我们自定义realms的时候就覆盖getAuthenticationInfo这个方法即可。

 

subject.checkRole原理

当用户调用subject.checkRole("role1")判断用户是否有对应的角色的时候,底层还是走的SecurityManager所属的Authorizer的checkRole方法。

hasRole然后又走了下面的方法

最后获取到了所有的realms,上篇文章说了java环境下使用了IniRealm,并且注入到了Authenticator(认证器)和Authorizer(授权器)的一个成员变量中。

所以getRealms就可以直接获取到所有的realms

因为IniRealms继承了AuthorizingRealm,而IniRealm没有实现hasRole方法,所以会走他的继承类AuthorizingRealm里面的hasRole来判断是否有权限。下面就是对应的方法。

在初始化IniRealm的时候会读取所有用户所属的role和permission并封装到成员变量中,getAuthorizationInfo方法就是返回了一个AuthorizationInfo对象里面获取了zhang所属role和permission。

所以我们自定义realm进行授权的时候就是覆盖了realm的getAuthorizationInfo方法,里面封装的role和permission都是从数据库查询出来的。

 

最后进行checkRole就很容易看懂了。

 

如果返回false,则Authorizer会抛出UnauthorizedException授权失败异常。

 

github地址

 

转载于:https://www.cnblogs.com/nfcm/p/9875657.html

你可能感兴趣的文章
JavaScript实现前端路由
查看>>
各大搜索引擎网站登录入口
查看>>
maven 搭建
查看>>
极速开发,快就是这么任性,你不知道的Jfinal2.0新特性
查看>>
Linux Notes
查看>>
iSCSI安装以及配置
查看>>
Lua脚本语法说明
查看>>
It is indirectly referenced from required .class file
查看>>
jenkins 自动化集成测试配置(一)
查看>>
php openssl 加密和解密 注意事项
查看>>
进程和线程之间的关系.
查看>>
总结CString、string、char*
查看>>
设置listview,隔行不同style
查看>>
【eoe Android特刊】第二十五期 Android 应用的终端适配
查看>>
Java菜鸟零基础自学入门必备视频教程
查看>>
Git忽略规则和.gitignore规则不生效的解决办法
查看>>
php实现汉诺塔问题
查看>>
linux c++ sqlite3
查看>>
Eclipse自动生成作者、日期注释等功能设置
查看>>
MySQL 按时间统计
查看>>