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的更多相关文章

  1. shiro中自定义realm实现md5散列算法加密的模拟

    shiro中自定义realm实现md5散列算法加密的模拟.首先:我这里是做了一下shiro 自定义realm散列模拟,并没有真正链接数据库,因为那样东西就更多了,相信学到shiro的人对连接数据库的一 ...

  2. 【三】shiro入门 之 Realm

    Realm:域,Shiro 从从Realm获取安全数据(如用户.角色.权限),就是说SecurityManager要验证用户身份,那么它需要从Realm获取相应的用户进行比较以确定用户身份是否合法:也 ...

  3. Shiro -- (三) 自定义Realm

    简介: Realm:域,Shiro 从从 Realm 获取安全数据(如用户.角色.权限),就是说 SecurityManager 要验证用户身份,那么它需要从 Realm 获取相应的用户进行比较以确定 ...

  4. shiro(二)自定义realm,模拟数据库查询验证

    自定义一个realm类,实现realm接口 package com; import org.apache.shiro.authc.*; import org.apache.shiro.realm.Re ...

  5. 使用Spring配置shiro时,自定义Realm中属性无法使用注解注入解决办法

    先来看问题    纠结了几个小时终于找到了问题所在,因为shiro的realm属于Filter,简单说就是初始化realm时,spring还未加载相关业务Bean,那么解决办法就是将springmvc ...

  6. shiro之自定义realm

    Shiro认证过程 创建SecurityManager--->主体提交认证--->SecurityManager认证--->Authenticsto认证--->Realm验证 ...

  7. 6、Shiro之自定义realm

    1.创建一个包存放我们自定义的realm文件: 创建一个类名为CustomRealm继承AuthorizingRealm并实现父类AuthorizingRealm的方法,最后重写: CustomRea ...

  8. shiro权限认证Realm的四大用法

    一.SimpleAccountRealm public class AuthenticationTest {          SimpleAccountRealm sar=new SimpleAcc ...

  9. Shiro探索1. Realm

    1. Realm 是什么?汉语意思:领域,范围:王国:这个比较抽象: 简单一点就是:Realm 用来对用户进行认证和角色授权的 再简单一点,一个用户怎么判断它有没有登陆?这个用户是什么角色有哪些权限? ...

随机推荐

  1. mysql 中find_in_set()和in()用法比较

    mysql 中find_in_set()和in()用法比较 在mysql中in可以包括指定的数字,而find_in_set()用于特定的数据类型. find_in_set 函数使用方法 个例子来说:有 ...

  2. php curl伪造来源ip和refer实例代码

    php curl伪造来源ip和来路refer实例代码1: //随机IP function Rand_IP(){ $ip2id= round(rand(600000, 2550000) / 10000) ...

  3. GitHub + circleCI 自动构建/自动部署 应用

    GitHub + circleCI 自动构建/自动部署, 这里略过了单元测试,以部署 laravel 应用为例子 比起 gitlab + ansible + genkins 操作起来节省了很多硬件资源 ...

  4. centOS 6.5关闭防火墙步骤

    centOS 6.5关闭防火墙步骤 关闭命令:  service iptables stop         永久关闭防火墙:chkconfig iptables off 两个命令同时运行,运行完成后 ...

  5. js操作cookie(转载:经测试可用)

    /***js操作cookie,star***/ function addCookie(objName,objValue,objsec){//添加cookie  var str = objName + ...

  6. Qt QTableWidget用法总结

    转载:李宏兵 QTableWidget是QT程序中常用的显示数据表格的空间,很类似于VC.C#中的DataGrid.说到QTableWidget,就必须讲一下它跟QTabelView的区别了. QTa ...

  7. pycharm中配置pep8

    Pycharm本身是有pep8风格检测的,当你敲得代码中不符合规范时,会有下划波浪线提示.如何让代码修改为符合规范,去掉这些难看的波浪线呢? 1.安装autopep8  pip install aut ...

  8. vertical-align表单元素垂直对齐

    原文地址:http://www.blueidea.com/tech/web/2009/6910.asp 最近的项目涉及到很多表单的制作,特别是复选框(checkbox)和单选框(radio).但是在前 ...

  9. 第11课 enum、sizeof、typedef 分析

    1. enum枚举类型 1.1 使用方法 (1)enum是C语言中的一种自定义类型 (2)enum值是可以根据需要自定义的的整型值 (3)第一个定义的enum值默认为0. (4)默认情况下的enum值 ...

  10. 探究CSS中border-top属性的使用

    上一节我们介绍了CSS top属性的用法,那么这节关于CSS border-top属性用法学习起来就会轻松一些,border-top 简写属性把上边框的所有属性设置到一个声明中. 本文向大家描述一下C ...