• 对shiro的AuthenticationStrategy的理解


    AuthenticationStrategy:认证策略,当给认证器Authenticator设置多个Realm时,要用到认证策略;认证策略的大致意思是:将多个realm返回的结果,按照什么样的认证策略来形成最终的认证结果。

    1:AuthenticationStrategy的继承和实现关系如下

    AuthenticationStrategy接口有个抽象类的实现AbstractAuthenticationStrategy;AbstractAuthenticationStrategy对AuthenticationStrategy接口定义的功能进行了实现。

    最常用的是AbstractAuthenticationStrategy的三个子类(通过重写方法对AbstractAuthenticationStrategy进行各自的改变):

    FirstSuccessfulStrategy:只要有一个Realm验证成功即可,只返回第一个Realm身份验证成功的认证信息,其他的忽略。

    AtLeastOneSuccessfulStrategy:只要有一个Realm验证成功即可,和FirstSuccessfulStrategy不同,将返回所有Realm身份验证成功的认证信息。

    AllSuccessfulStrategy:所有Realm验证成功才算成功,且返回所有Realm身份验证成功的认证信息,如果有一个失败就失败了。

    2:AuthenticationStrategy接口中的四个方法如下:

    3:AuthenticationStrategy接口的实现类AbstractAuthenticationStrategy中多了一个merge方法

    beforeAllAttempts:用于生成合并对象,合并对象用来合并各个realm生成的AuthenticationInfo对象。

    beforeAttempt:仅仅将传入的合并对象返回,不做其他处理

    afterAttempt:将realm返回的AuthenticationInfo对象和合并对象进行判断,并调用合并方法进行合并。

    afterAllAttempts:将最终的合并对象返回

    merge:合并realm返回的AuthenticationInfo对象和合并对象。

    4:根据下面shiro的ModularRealmAuthenticator的doMultiRealmAuthentication方法中认证策略的使用,对认证策略进行总结:

    1.  protected AuthenticationInfo doMultiRealmAuthentication(Collection<Realm> realms, AuthenticationToken token) {
    2.         AuthenticationStrategy strategy = getAuthenticationStrategy();
    3.         AuthenticationInfo aggregate = strategy.beforeAllAttempts(realms, token);
    4.         if (log.isTraceEnabled()) {
    5.             log.trace("Iterating through {} realms for PAM authentication", realms.size());
    6.         }
    7.         for (Realm realm : realms) {
    8.             aggregate = strategy.beforeAttempt(realm, token, aggregate);
    9.             if (realm.supports(token)) {
    10.                 log.trace("Attempting to authenticate token [{}] using realm [{}]", token, realm);
    11.                 AuthenticationInfo info = null;
    12.                 Throwable t = null;
    13.                 try {
    14.                     info = realm.getAuthenticationInfo(token);
    15.                 } catch (Throwable throwable) {
    16.                     t = throwable;
    17.                     if (log.isDebugEnabled()) {
    18.                         String msg = "Realm [" + realm + "] threw an exception during a multi-realm authentication attempt:";
    19.                         log.debug(msg, t);
    20.                     }
    21.                 }
    22.                 aggregate = strategy.afterAttempt(realm, token, info, aggregate, t);
    23.             } else {
    24.                 log.debug("Realm [{}] does not support token {}.  Skipping realm.", realm, token);
    25.             }
    26.         }
    27.         aggregate = strategy.afterAllAttempts(token, aggregate);
    28.         return aggregate;
    29.     }

    通过上面的代码对AbstractAuthenticationStrategy的认证流程总结如下:

    (1)在循环遍历realms前,生成一个合并对象(beforeAllAttempts)

    (2)在循环内,调用realm前,仅仅将合并对象返回(beforeAttempt)

    (3)在循环内,调用realm后,将realm返回的对象和合并对象进行合并(afterAttempt,merge)

    (4)在循环遍历realms后,将合并对象返回(afterAllAttempts)

    理解:将多个realm认证的结果合并在一起,并最终返回。

    5:FirstSuccessfulStrategy(只要有一个Realm验证成功即可,只返回第一个Realm身份验证成功的认证信息,其他的忽略),所以我们只需要重写AbstractAuthenticationStrategy的merge方法(合并对象的过程),在该方法内,只需要将合并对象保持为第一个认证成功的realm返回的对象即可。(这里还需要验证,不明白最终如果所有realm验证失败了,会是什么结果?)

    6:AtLeastOneSuccessfulStrategy(只要有一个Realm验证成功即可,和FirstSuccessfulStrategy不同,将返回所有Realm身份验证成功的认证信息),所以我们只需要重写AbstractAuthenticationStrategy的afterAllAttempts方法(即所有realm认证以后),在该方法内,对合并对象进行判断,如果合并对象为空或者合并对象内没有任何的认证通过的主体信息,则说明没有任何一个Realm验证成功,所以最终结果是失败。

    7:AllSuccessfulStrategy(所有Realm验证成功才算成功,且返回所有Realm身份验证成功的认证信息,如果有一个失败就失败了),所以我们需要重写AbstractAuthenticationStrategy的afterAttempt方法(即每个realm认证后),在方法内,对每次realm返回的对象都进行判断,只要有一个是失败,则整个认证过程就是失败的。(这里也需要验证一下,看如果抛出了运行时异常,catch能捕获到吗?)

  • 相关阅读:
    rt_list_entry() 函数
    替换空格
    跳台阶
    斐波那契数列
    基于5221码的同步十进制加法计数器
    强连通分量+Tarjia+缩点
    次小生成树
    差分约束
    P1547 Out of Hay
    P1197 [JSOI2008]星球大战
  • 原文地址:https://www.cnblogs.com/hzcya1995/p/13302480.html
Copyright © 2020-2023  润新知