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. Android ViewPager Fragment使用懒加载提升性能

     Android ViewPager Fragment使用懒加载提升性能 Fragment在如今的Android开发中越来越普遍,但是当ViewPager结合Fragment时候,由于Androi ...

  2. nat转换

    实验目的: (1)     了解nat转换 (2)     了解nat转换配置命令 (3)     了解哪些是私有ip地址哪些不是私有ip地址 实验工具: 华为eNSP模拟器和Wireshar 实验拓 ...

  3. Sublime Text 3安装插件指南

    Sublime Text已经很用得很广泛,一般普通的功能已经够用,加入一些插件能些许加快开发. 安装 Package Control 有了插件控制器Package Control安装起来就很轻松了. ...

  4. Array.sort()方法

    Array.sort()方法将数组中的元素排序并返回排序后的数组. 当不带参数时,默认按照顺序排序,也就是从小到大.当然,也可以直接给sort加一个比较函数比较. ,,]; arr.sort(); c ...

  5. Linux压缩那些事儿

    tar简介 Linux的压缩命令的源文件只能有一个,这意味在压缩之前不得不先将要压缩的所有文件打包成一个包,然后再压缩包,这样来完成对多个文件的压缩.所以在了解解压缩之前就必须先了解打包命令. Lin ...

  6. Flume 实战(1) -- 初体验

    前言: Flume-ng是数据收集/聚合/传输的组件, Flume-ng抛弃了Flume OG原本繁重的zookeeper和Master, Collector, 其整体的架构更加的简洁和明了. 其基础 ...

  7. qsort函数用法【转】

    qsort函数用法 qsort 功 能: 使用快速排序例程进行排序  用 法: void qsort(void *base, int nelem, int width, int (*fcmp)(con ...

  8. POJ 3176 简单DP

    Cow Bowling Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 16448 Accepted: 10957 Descrip ...

  9. codeforces195a

    link:http://codeforces.com/problemset/problem/336/A 很简单的一道题目,当初有个单词不认识,isosceles原来意思是等腰的o(╯□╰)o #inc ...

  10. LeetCode() Min Stack 不知道哪里不对,留待。

    class MinStack { public: MinStack() { coll.resize(2); } void push(int x) { if(index == coll.size()-1 ...