shiro 方法级别细粒度权限控制_第四章:Shiro的身份认证(Authentication)——深入浅出学Shiro细粒度权限开发框架——私塾在线原创...

nStep3:SubjectManager 接收token 以及简单地委托给内部的Authenticator 实例通过调用authenticator.authenticate(token)。这通常是一个ModularRealmAuthenticator 实例,支持在身份验证中协调一个或多个Realm 实例。

n

nStep 4:如果应用程序中配置了一个以上的Realm,ModularRealmAuthenticator 实例将利用配置好的AuthenticationStrategy 来启动Multi-Realm 认证尝试。在Realms 被身份验证调用之前,期间和以后,AuthenticationStrategy 被调用使其能够对每个Realm 的结果作出反应。

n

nStep 5:每个配置的Realm 用来帮助看它是否支持提交的AuthenticationToken。如果支持,那么支持Realm 的getAuthenticationInfo 方法将会伴随着提交的token 被调用。getAuthenticationInfo 方法有效地代表一个特定Realm 的单一的身份验证尝试。

初识自定义

Realm

n这里先来个例子,认识一下:

public class MyRealm extends AuthorizingRealm{

protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {

String userName = (String) getAvailablePrincipal(principals);

//通过用户名去获得用户的所有资源,并把资源存入info中

SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();

Set s = new HashSet();

s.add("p1");  s.add("p2"); info.setStringPermissions(s);

Set r = new HashSet();

r.add("r1"); r.add("r2"); info.setRoles(r);

return info;}

protected AuthenticationInfo doGetAuthenticationInfo(

AuthenticationToken token) throws AuthenticationException {

//token中储存着输入的用户名和密码

UsernamePasswordToken upToken = (UsernamePasswordToken)token;

String username = upToken.getUsername();

String password = String.valueOf(upToken.getPassword());

//通常是与数据库中用户名和密码进行比对,这里就省略了

//比对成功则返回info,比对失败则抛出对应信息的异常AuthenticationException

SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(username, password .toCharArray(),getName());

return info;  }}

配置多个Realm

n上面的例子可以作为第一个Realm

n再复制一份,定义为MyRealm2,在返回user前添加抛出一个例外,表示认真没有通过,如下:

if(username.equals("javass")){

throw new AuthenticationException("MyRealm2 认证失败");

}

SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(username, password .toCharArray(),getName());

n在配置文件里面添加Realm的定义

myRealm1=cn.javass.hello.MyRealm

myRealm2=cn.javass.hello.MyRealm2

由于有多个realm,一般就需要配置AuthenticationStrategy了,而AuthenticationStrategy是跟Authenticator(认证器)相关的。

n配置Authenticator和AuthenticationStrategy

authenticator = org.apache.shiro.authc.pam.ModularRealmAuthenticator

authcStrategy = org.apache.shiro.authc.pam.AllSuccessfulStrategy

authenticator.authenticationStrategy = $authcStrategy

authenticator.realms=$myRealm2,$myRealm1

n当然,你可以扩展并实现自己的Authenticator,一般没有必要

n最后把Authenticator设置给securityManager

securityManager.authenticator = $authenticator

n关于AuthenticationStrategy的配置,有三种:

AtLeastOneSuccessfulStrategy :如果一个(或更多)Realm 验证成功,则整体的尝试被认为是成功的。如果没有一个验证成功,则整体尝试失败。

FirstSuccessfulStrategy 只有第一个成功地验证的Realm 返回的信息将被使用。所有进一步的Realm 将被忽略。如果没有一个验证成功,则整体尝试失败

AllSucessfulStrategy 为了整体的尝试成功,所有配置的Realm 必须验证成功。如果没有一个验证成功,则整体尝试失败。

ModularRealmAuthenticator 默认的是AtLeastOneSuccessfulStrategy

n自定义自己的AuthenticationStrategy,通常是扩展自AbstractAuthenticationStrategy,示例如下:

public class MyAuthenticationStrategy extends AbstractAuthenticationStrategy{

public AuthenticationInfo afterAttempt(Realm realm, AuthenticationToken token, AuthenticationInfo singleRealmInfo, AuthenticationInfo aggregateInfo, Throwable t) throws AuthenticationException {

if(realm.getName().equals("myRealm2")){

if(singleRealmInfo==null || singleRealmInfo.getPrincipals()==null){

throw new AuthenticationException("主战认证未通过");

}

}

return super.afterAttempt(realm, token, singleRealmInfo, aggregateInfo, t);

}

}

至于具体覆盖扩展什么方法,需要根据你具体的策略来定。

多个Realm的验证顺序

n概述

非常重要的一点是:ModularRealmAuthenticator 将与Realm 实例以迭代的顺序进行交互。

在SecurityManager 中已经配置好了ModularRealmAuthenticator 对Realm实例的访问。当执行一个认证尝试时,它将会遍历该集合,并对每一个支持提交AuthenticationToken 的Realm 调用Realm 的getAuthenticationInfo 方法

n隐式排列

当你配置多个realm的时候,处理的顺序默认就是你配置的顺序。

这种情况通常就是只定义了realm,而没有配置securityManager的realms

n显示排列

也就是显示的配置securityManager.realms,那么执行的顺序就是你配置该值的realm的顺序。

通常更推荐显示排列。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值