shiro多realm的spring-boot案例剖析

shiro多realm整合的spring-boot案例剖析

    概述:shiro认证的流程主要是通过securityManager调用login(Subject subject, AuthenticationToken token)方法,实际上委托的是Authenticator(认证器进行认证),默认情况下使用的是

ModularRealmAuthenticator认证器,如果我们只有1个realm,最终的认证操作就是调用这个realm,如果我们有多个realm呢?这个时候就需要我们对ModularRealmAuthenticator认证器进行扩展。

一、下面是subject.login()执行的代码调用片段

    public void login(AuthenticationToken token) throws AuthenticationException {
        clearRunAsIdentitiesInternal();
        Subject subject = securityManager.login(this, token);

上面是DelegatingSubject的login方法

    public Subject login(Subject subject, AuthenticationToken token) throws AuthenticationException {
        AuthenticationInfo info;
        try {
            info = authenticate(token);
        } catch (AuthenticationException ae) {
        
        }
    }

上面是DefaultSecurityManager的login方法

    public AuthenticationInfo authenticate(AuthenticationToken token) throws AuthenticationException {
        return this.authenticator.authenticate(token);
    }

实际调用的是AuthenticatingSecurityManager的authenticate方法, 这个this.authenticator就是ModularRealmAuthenticator。

二、ModularRealmAuthenticator默认的多reaml是按什么策略进行处理的呢?

1、authenticate方法的公共处理,实际上调用的是doAuthenticate(token)方法。

 public final AuthenticationInfo authenticate(AuthenticationToken token) throws AuthenticationException {
      AuthenticationInfo info;
        try {
            info = doAuthenticate(token); // 实际主要的认证方法
            if (info == null) { // 没有返回info就抛出auth异常
                throw new AuthenticationException(msg);
            }
        } catch (Throwable t) {
            AuthenticationException ae = null;
            if (t instanceof AuthenticationException) {
                ae = (AuthenticationException) t;
            }
            if (ae == null) {
                ae = new AuthenticationException(msg, t);
            } // 任何认证过程异常包装成auth异常进行抛出
            throw ae;
        }
        return info;
    }

2、我们看看doAuthenticate的默认实现,根据配置了realms的个数来判断是调用单个还是doMultiRealmAuthentication()方法

protected AuthenticationInfo doAuthenticate(AuthenticationToken authenticationToken) throws AuthenticationException {
     assertRealmsConfigured();
    Collection<Realm> realms = getRealms();
    if (realms.size() == 1) {
        return doSingleRealmAuthentication(realms.iterator().next(), authenticationToken);
    } else {
        return doMultiRealmAuthentication(realms, authenticationToken);
    }
}

 3、在说doMultiRealmAuthentication方法前,我们可以在ModularRealmAuthenticator类里找到new的AuthenticationStrategy策略。这个策略决定了doMultiRealmAuthentication的实现方式。我们先看看AbstractAuthenticationStrategy的默认实现。

public abstract class AbstractAuthenticationStrategy implements AuthenticationStrategy {

    // 全部realm认证前--创建一个空info
    public AuthenticationInfo beforeAllAttempts(Collection<? extends Realm> realms, AuthenticationToken token) throws AuthenticationException {
        return new SimpleAuthenticationInfo();
    }

    // 单个realm认证前--直接返回
    public AuthenticationInfo beforeAttempt(Realm realm, AuthenticationToken token, AuthenticationInfo aggregate) throws AuthenticationException {
        return aggregate;
    }

    // 单个realm认证前--将上一个和此次的info进行合并
    public AuthenticationInfo afterAttempt(Realm realm, AuthenticationToken token, AuthenticationInfo singleRealmInfo, AuthenticationInfo aggregateInfo, Throwable t) throws AuthenticationException {
        AuthenticationInfo info;
        if (singleRealmInfo == null) {
   
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值