1、AuthenticationStrategy实现

//在所有Realm验证之前调用
AuthenticationInfo beforeAllAttempts(
Collection<? extends Realm> realms, AuthenticationToken token)
throws AuthenticationException;
//在每个Realm之前调用
AuthenticationInfo beforeAttempt(
Realm realm, AuthenticationToken token, AuthenticationInfo aggregate)
throws AuthenticationException;
//在每个Realm之后调用
AuthenticationInfo afterAttempt(
Realm realm, AuthenticationToken token,
AuthenticationInfo singleRealmInfo, AuthenticationInfo aggregateInfo, Throwable t)
throws AuthenticationException;
//在所有Realm之后调用
AuthenticationInfo afterAllAttempts(
AuthenticationToken token, AuthenticationInfo aggregate)
throws AuthenticationException;

因为每个AuthenticationStrategy实例都是无状态的,所有每次都通过接口将相应的认证信息传入下一次流程;通过如上接口可以进行如合并/返回第一个验证成功的认证信息。

  自定义实现时一般继承org.apache.shiro.authc.pam.AbstractAuthenticationStrategy

下边这个OnlyOneAuthenticatorStrategy只允许一个成功的验证信息,进行返回,否则会报AuthenticationException,只返回第一个验证成功的Realm的认证信息

public class OnlyOneAuthenticatorStrategy extends AbstractAuthenticationStrategy {

    @Override
public AuthenticationInfo beforeAllAttempts(Collection<? extends Realm> realms, AuthenticationToken token) throws AuthenticationException {
return new SimpleAuthenticationInfo();//返回一个权限的认证信息,在进行验证之前返回的信息,不对权限信息进行处理
} @Override
public AuthenticationInfo beforeAttempt(Realm realm, AuthenticationToken token, AuthenticationInfo aggregate) throws AuthenticationException {
return aggregate;//返回之前合并的,在进行验证之前返回的信息,不对权限信息进行处理
  }
  @Override
  public AuthenticationInfo afterAttempt(Realm realm, AuthenticationToken token, AuthenticationInfo singleRealmInfo, AuthenticationInfo aggregateInfo, Throwable t) throws AuthenticationException {
     AuthenticationInfo info;
     if (singleRealmInfo == null)
     {
       info = aggregateInfo;
     } else
    {
       if (aggregateInfo == null) {
       info = singleRealmInfo;
     } else {
       info = merge(singleRealmInfo, aggregateInfo);
       if(info.getPrincipals().getRealmNames().size() > 1)
       {
         System.out.println(info.getPrincipals().getRealmNames());
         throw new AuthenticationException("Authentication token of type [" + token.getClass() + "] " +
        "could not be authenticated by any configured realms. Please ensure that only one realm can " +
         "authenticate these tokens.");
       }
     }
   }
     return info;
}
@Override
public AuthenticationInfo afterAllAttempts(AuthenticationToken token, AuthenticationInfo aggregate) throws AuthenticationException
{
    return aggregate;
} }

这里的shiro主要就是将多个AuthenticationToken信息合并在一起,

2、AbstractAuthenticationStrategy中的merge方法,主要就是先检查该

AuthenticationInfo 是不是可以merge的类型,如果是则将其转换为可以merge的类型,然后调用merge方法
/**
* Merges the specified <code>info</code> argument into the <code>aggregate</code> argument and then returns an
* aggregate for continued use throughout the login process.
* <p/>
* This implementation merely checks to see if the specified <code>aggregate</code> argument is an instance of
* {@link org.apache.shiro.authc.MergableAuthenticationInfo MergableAuthenticationInfo}, and if so, calls
* <code>aggregate.merge(info)</code> If it is <em>not</em> an instance of
* <code>MergableAuthenticationInfo</code>, an {@link IllegalArgumentException IllegalArgumentException} is thrown.
* Can be overridden by subclasses for custom merging behavior if implementing the
* {@link org.apache.shiro.authc.MergableAuthenticationInfo MergableAuthenticationInfo} is not desired for some reason.
*/
protected AuthenticationInfo merge(AuthenticationInfo info, AuthenticationInfo aggregate) {
if( aggregate instanceof MergableAuthenticationInfo ) {
((MergableAuthenticationInfo)aggregate).merge(info);
return aggregate;
} else {
throw new IllegalArgumentException( "Attempt to merge authentication info from multiple realms, but aggregate " +
"AuthenticationInfo is not of type MergableAuthenticationInfo." );
}
}

可以进行多个AuthenticationInfo信息进行merge的功能如下所示,返回所有验证成功的Realm的认证信息

public class AtLeastTwoAuthenticatorStrategy extends AbstractAuthenticationStrategy {

    @Override
public AuthenticationInfo beforeAllAttempts(Collection<? extends Realm> realms, AuthenticationToken token) throws AuthenticationException {
return new SimpleAuthenticationInfo();//返回一个权限的认证信息
} @Override
public AuthenticationInfo beforeAttempt(Realm realm, AuthenticationToken token, AuthenticationInfo aggregate) throws AuthenticationException {
return aggregate;//返回之前合并的
} @Override
public AuthenticationInfo afterAttempt(Realm realm, AuthenticationToken token, AuthenticationInfo singleRealmInfo, AuthenticationInfo aggregateInfo, Throwable t) throws AuthenticationException {
AuthenticationInfo info;
if (singleRealmInfo == null) {
info = aggregateInfo;
} else {
if (aggregateInfo == null) {
info = singleRealmInfo;
} else {
info = merge(singleRealmInfo, aggregateInfo);
}
} return info;
} @Override
public AuthenticationInfo afterAllAttempts(AuthenticationToken token, AuthenticationInfo aggregate) throws AuthenticationException {
if (aggregate == null || CollectionUtils.isEmpty(aggregate.getPrincipals()) || aggregate.getPrincipals().getRealmNames().size() < 2) {
throw new AuthenticationException("Authentication token of type [" + token.getClass() + "] " +
"could not be authenticated by any configured realms. Please ensure that at least two realm can " +
"authenticate these tokens.");
} return aggregate;
}

3、对于Subject线程进行解绑

@After
public void tearDown() throws Exception {
ThreadContext.unbindSubject();//退出时请解除绑定Subject到线程 否则对下次测试造成影响
}

32、shiro 框架入门三的更多相关文章

  1. 34、Shiro框架入门三,角色管理

    //首先这里是java代码,就是根据shiro-role.ini配置文件中的信息来得到role与用户信息的对应关系//从而来管理rolepublic class TestShiroRoleTest e ...

  2. 【原创】NIO框架入门(三):iOS与MINA2、Netty4的跨平台UDP双向通信实战

    前言 本文将演示一个iOS客户端程序,通过UDP协议与两个典型的NIO框架服务端,实现跨平台双向通信的完整Demo.服务端将分别用MINA2和Netty4进行实现,而通信时服务端你只需选其一就行了.同 ...

  3. 30、shiro框架入门2,关于Realm

    1.Jdbc的Realm链接,并且获取权限 首先创建shiro-jdbc.ini的配置文件,主要配置链接数据库的信息 配置文件中的内容如下所示 1.变量名=全限定类名会自动创建一个类实例 2.变量名. ...

  4. 29、shiro框架入门

    1.建立测试shiro框架的项目,首先建立的项目结构如下图所示 ini文件 中的内容如下图所示 pom.xml文件中的内容如下所示 <project xmlns="http://mav ...

  5. 32、shiro框架入门3.授权

    一. 授权,也叫访问控制,即在应用中控制谁能访问哪些资源(如访问页面/编辑数据/页面操作等).在授权中需了解的几个关键对象:主体(Subject).资源(Resource).权限(Permission ...

  6. 使用Spring框架入门三:基于XML配置的AOP的使用

    一.引入Jar包 <!--测试1使用--> <dependency> <groupId>org.springframework</groupId> &l ...

  7. 【原创】NIO框架入门(四):Android与MINA2、Netty4的跨平台UDP双向通信实战

    概述 本文演示的是一个Android客户端程序,通过UDP协议与两个典型的NIO框架服务端,实现跨平台双向通信的完整Demo. 当前由于NIO框架的流行,使得开发大并发.高性能的互联网服务端成为可能. ...

  8. 【原创】NIO框架入门(二):服务端基于MINA2的UDP双向通信Demo演示

    前言 NIO框架的流行,使得开发大并发.高性能的互联网服务端成为可能.这其中最流行的无非就是MINA和Netty了,MINA目前的主要版本是MINA2.而Netty的主要版本是Netty3和Netty ...

  9. 【原创】NIO框架入门(一):服务端基于Netty4的UDP双向通信Demo演示

    申明:本文由作者基于日常实践整理,希望对初次接触MINA.Netty的人有所启发.如需与作者交流,见文签名,互相学习. 学习交流 更多学习资料:点此进入 推荐 移动端即时通讯交流: 215891622 ...

随机推荐

  1. linux下实时监测tomcat关闭并启动

    linux下tomcat总是会无故出现自动关闭的情况,在暂时无法解决该问题时,就需要一个东西能实时监测tomcat是否还正常的运行,若发现已关闭时,执行启动命令. 我们可以添加一个shell脚本来实现 ...

  2. 修改LR自带的示例程序端口号

    问题:LoadRunner的HP Web Tours 应用程序服务启动不了,提示1080端口被占用的问题 解决方法: 查看占用1080端口的进程 Cmd 窗口输入netstat –ano  找到占用该 ...

  3. [翻译]lpeg入门教程

    原文地址:http://lua-users.org/wiki/LpegTutorial 简单匹配 LPeg是一个用于文本匹配的有力表达方式,比Lua原生的字符串匹配和标准正则表达式更优异.但是,就像其 ...

  4. Java-->xml的pull解析

    --> pull解析器是android内置的解析器,解析原理与sax类似 --> xml文件student.xml: <?xml version="1.0" en ...

  5. [Debian]8.2升8.3

    $ uname -mrs $ lsb_release -a $ sudo apt-get update#開始升級 $ sudo apt-get dist-upgrade $ sudo reboot#重 ...

  6. 关于debug时的一些操作

    当进入一个for循环时,想要看i==49或者其它的行,可以进行如下操作: 在for循环中打断点,点击鼠标右键,选择如下: 在弹出的页面中选择Breakpoint Properties,输入i==49, ...

  7. 一个简单的Lua解释器

    #include "stdafx.h" #include<stdarg.h> #include<stdlib.h> #include<stdio.h& ...

  8. Android项目——读取手机联系人信息

    加入读取联系人信息的权限 <uses-permission android:name="android.permission.READ_CONTACTS"/> cont ...

  9. docvalues和Fieldcache

    Fieldcache:  docID->document->fieldvalue 无论是聚类排序关联等,首先都需要获得文档中某个字段的值,通过docID去获得整个document,然后再去 ...

  10. dubbo 转

      http://blog.csdn.net/zhiguozhu/article/details/50517513 背景 随着互联网的发展,网站应用的规模不断扩大,常规的垂直应用架构已无法应对,分布式 ...