(4)shiro多个realm
shiro支持多个realm,当设置多个realm的时候,shiro的认证和授权的步骤是怎样的呢。
多个realm认证原理:
发现需要在执行认证的时候,需要策略来处理多个realm存在的情况。默认实现类有三个策略:
1. AtLeastOneSuccessfulStrategy :如果一个(或更多)Realm 验证成功,则整体的尝试被认为是成功的。如果没有一个验证成功,则整体尝试失败。
2. FirstSuccessfulStrategy 只有第一个成功地验证的Realm 返回的信息将被使用。后面的realm会被忽略,如果一个都没有成功则失败。
3. AllSucessfulStrategy 为了整体的尝试成功,所有配置的Realm 必须验证成功。如果没有一个验证成功,则整体尝试失败。
ModularRealmAuthenticator 默认的是AtLeastOneSuccessfulStrategy
多个realm授权原理:
当shiro判断是否有对应的角色或者资源的时候,最底层是调用Authenticator的doAuthenticate方法。
下面是Authenticator的一个实现类(ModularRealmAuthenticator)当有多个realms的时候执行的步骤:
得到总结:只要有一个realm里面有这个角色或者资源就代表有这个权限
代码测试
1,新增一个realm2,无论如何都是通过的,返回的principal固定为test(自己可以根据业务需要,为当前登录的用户设置别的身份)
public class MyRealm2 extends AuthorizingRealm { //认证信息,
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
UsernamePasswordToken upToken = (UsernamePasswordToken) token; String password = new String(upToken.getPassword());
//模拟用户名密码是否正确
return new SimpleAuthenticationInfo("test",password,getName()); } //授权
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
//获取用户名
String username = (String)getAvailablePrincipal(principals);
//模拟从数据库查询出来对应的角色和权限
Set<String> roles = new HashSet<String>();
roles.add("role_3");
roles.add("role_4"); Set<String> permissions = new HashSet<String>();
permissions.add("user:update"); SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
info.setRoles(roles);
info.setStringPermissions(permissions);
return info;
}
2配置文件
myrealm=com.nfcm.shiro.Realm.MyRealm
myrealm2=com.nfcm.shiro.Realm.MyRealm2
#设置策略,必须所有的realm都通过
authcStrategy=org.apache.shiro.authc.pam.AllSuccessfulStrategy
#配置认证器
authenticator=org.apache.shiro.authc.pam.ModularRealmAuthenticator
#将验证器和策略关联起来
authenticator.authenticationStrategy=$authcStrategy
#注入认证器
securityManager.authenticator=$authenticator
#设置realm,这个要最后设置,如果后设置认证器或者授权器,则里面的realms都是空的
securityManager.realms=$myrealm,$myrealm2
3.测试代码
ShiroUtils.login("classpath:shiro-myrealm2.ini","zhang","123456"); Subject subject = SecurityUtils.getSubject(); List<String> principals =subject.getPrincipals().asList();
for (String principal:principals) {
System.out.println(principal);
} System.out.println(subject.getPrincipals().getPrimaryPrincipal());
//是否通过认证
System.out.println(subject.isAuthenticated());
//是否有role1角色
System.out.println(subject.hasRole("role_1"));
//realm2里面的角色
System.out.println(subject.hasRole("role_3")); System.out.println(subject.isPermitted("user:create"));
//realm2里面的资源
System.out.println(subject.isPermitted("user:update"));
最后输出结果:
zhang
test
zhang
true
true
true
true
true
getPrimaryPrincipal方法获取的是第一个realm里面的身份。
subject.getPrincipals().fromRealm("myrealm2")可以获取指定的realm里面的身份信息,返回的是一个集合,获取第一个即可。
github代码地址
https://github.com/cmniefei/shiroparent
(4)shiro多个realm的更多相关文章
- shiro中自定义realm实现md5散列算法加密的模拟
shiro中自定义realm实现md5散列算法加密的模拟.首先:我这里是做了一下shiro 自定义realm散列模拟,并没有真正链接数据库,因为那样东西就更多了,相信学到shiro的人对连接数据库的一 ...
- 【三】shiro入门 之 Realm
Realm:域,Shiro 从从Realm获取安全数据(如用户.角色.权限),就是说SecurityManager要验证用户身份,那么它需要从Realm获取相应的用户进行比较以确定用户身份是否合法:也 ...
- Shiro -- (三) 自定义Realm
简介: Realm:域,Shiro 从从 Realm 获取安全数据(如用户.角色.权限),就是说 SecurityManager 要验证用户身份,那么它需要从 Realm 获取相应的用户进行比较以确定 ...
- shiro(二)自定义realm,模拟数据库查询验证
自定义一个realm类,实现realm接口 package com; import org.apache.shiro.authc.*; import org.apache.shiro.realm.Re ...
- 使用Spring配置shiro时,自定义Realm中属性无法使用注解注入解决办法
先来看问题 纠结了几个小时终于找到了问题所在,因为shiro的realm属于Filter,简单说就是初始化realm时,spring还未加载相关业务Bean,那么解决办法就是将springmvc ...
- shiro之自定义realm
Shiro认证过程 创建SecurityManager--->主体提交认证--->SecurityManager认证--->Authenticsto认证--->Realm验证 ...
- 6、Shiro之自定义realm
1.创建一个包存放我们自定义的realm文件: 创建一个类名为CustomRealm继承AuthorizingRealm并实现父类AuthorizingRealm的方法,最后重写: CustomRea ...
- shiro权限认证Realm的四大用法
一.SimpleAccountRealm public class AuthenticationTest { SimpleAccountRealm sar=new SimpleAcc ...
- Shiro探索1. Realm
1. Realm 是什么?汉语意思:领域,范围:王国:这个比较抽象: 简单一点就是:Realm 用来对用户进行认证和角色授权的 再简单一点,一个用户怎么判断它有没有登陆?这个用户是什么角色有哪些权限? ...
随机推荐
- 使用redis防止商品超发
redis不仅仅是单纯的缓存,它还有一些特殊的功能,在一些特殊场景上很好用.redis中key的原子自增incrby和判断key不存在再写入的setnx方法,可以有效的防止超发. 下面使用两个不同的方 ...
- TFS错误-TF249053
前几天规划了下代码结构,改了很多东西后,台式机依然正常访问,但是笔记本一连接或者更改TFS相关资源就报错TF249053.报错点击后不影响正常使用,但是很郁闷.于是查了下资料如下. 错误原因: htt ...
- js的自定义事件
js中的事件是js的一大技术点,说白了就是操作dom树的唯一途径. 关于事件无非两种绑定方式: document.getElementById('xxx').onclick = function(){ ...
- java web 中 页面/业务重定向
情形一:地址栏简洁明了(列表页面需要局部查询,分页) 页面初始化:library方法,没有任何过滤条件,显示第一页: 页面刷新:library方法,page依旧保留,在地址栏中显示,但局部查询条件会 ...
- 用linux的iconv函数 转换编码
inux shell 配置文件中默认的字符集编码为UTF-8 .UTF-8是unicode的一种表达方式,gb2312是和unicode都是字符的编码方式,所以说gb2312跟utf-8的概念应该不是 ...
- python unittest单元测试框架-2discover
基于TestLoader提供的discover方法实现用例执行 当用例达达到数十条后,在runtest.py文件中通过addTest()添加/删除测试用例就非常麻烦.此时可以使用discover方法找 ...
- python selenium-9 grid模式
grid是进行分布式测试的工具,由一个hub主节点和若干个node代理节点组成 1.下载Selenium Standalone Server 下载地址:https://www.seleniumhq.o ...
- php multicast多播实现详解
什么是多播? 网络中存在3中传播形式,单播,广播,多播. 1. 单播 : 就是1->1 2. 广播 : 1->多(广播域内) 3. 多播 : 1->组(一组ip) 1 2 3 4 5 ...
- (转)手机的AP和BP是什么?
AP:Application Processor,即应用芯片 BP:Baseband Processor,即基带芯片 搞什么嘛,双核就双核呗,怎么又搞出个AP和BP啊 原来,FCC(美国联邦通信委员会 ...
- 基于Vue的Ui框架
基于Vue的Ui框架 饿了么公司基于vue开的的vue的Ui组件库 Element Ui 基于vue pc端的UI框架 http://element.eleme.io/ MintUi 基于vue 移动 ...