shiro 登录验证身份过程分析

//步骤1:首先利用工具类获取Subject,没有获取到则创建一个新的Subject
Subject currentUser = SecurityUtils.getSubject();

//步骤2:在默认实现类DelegatingSubject中执行登录验证过程

public void login(AuthenticationToken token) throws AuthenticationException {

//只列出核心代码 
//调用 securityManager验证登录           

Subject subject = securityManager.login(this, token);

PrincipalCollection principals;

String host = null;

//登录成功后获取用户实体类
if (subject instanceof DelegatingSubject) {
    DelegatingSubject delegating = (DelegatingSubject) subject;
    principals = delegating.principals;
    host = delegating.host;
} else {
    principals = subject.getPrincipals();
}



}

现在分析   Subject subject = securityManager.login(this, token);执行过程

在DefaultSecurityManager实现类中

 public Subject login(Subject subject, AuthenticationToken token) throws AuthenticationException {
        AuthenticationInfo info;
        try {
           //验证token
            info = authenticate(token);
        } catch (AuthenticationException ae) {
            try {
                onFailedLogin(token, ae, subject);
            } catch (Exception e) {
                if (log.isInfoEnabled()) {
                    log.info("onFailedLogin method threw an " +
                            "exception.  Logging and propagating original AuthenticationException.", e);
                }
            }
            throw ae; //propagate
        }

        
        Subject loggedIn = createSubject(token, info, subject);

        onSuccessfulLogin(token, info, loggedIn);

        return loggedIn;
    }

看看方法authenticate(token),该方法在父类 AuthenticatingSecurityManager中,下面的继承上面的类,继承结构为

   

interface SecurityManager, Destroyable, CacheManagerAware, EventBusAware
 abstract CachingSecurityManager
    abstract RealmSecurityManager
            abstract  AuthenticatingSecurityManager

                             abstract  AuthorizingSecurityManager

                                     class     SessionsSecurityManager

                                             class     DefaultSecurityManager

 

public AuthenticationInfo authenticate(AuthenticationToken token) throws AuthenticationException {
         //利用authenticator去验证
        return this.authenticator.authenticate(token);
    }

securityManager内容关于认证代码全部依赖类 Authenticator 去验证

public AuthenticatingSecurityManager() {
        super();
        this.authenticator = new ModularRealmAuthenticator();
    }

默认实现类为  ModularRealmAuthenticator ,继承结构为

 

interface   Authenticator, LogoutAware

      abstract  AbstractAuthenticator

            class  ModularRealmAuthenticator

其中AbstractAuthenticator,该类实现了自定义注册验证失败通知类,方便用户处理验证失败,    该类中实现了接口Authenticator的方法:

  public final AuthenticationInfo authenticate(AuthenticationToken token) throws AuthenticationException {

       //已删除非核心代码

        AuthenticationInfo info;
        try {
            //调用模板方法,子类实现,这里的子类就是 ModularRealmAuthenticator 
            info = doAuthenticate(token);
            if (info == null) {
              
                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);
               
            }
            try {
                //通知注册的类失败
                notifyFailure(token, ae);
            } catch (Throwable t2) {
              
                }
            }


            throw ae;
        }

       
        notifySuccess(token, info);

        return info;
    }

子类 ModularRealmAuthenticator方法:

 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);
        }
    }

可以看出,实际执行验证的是接口Realm的实现类,继承机构:

interface Realm, Nameable, CacheManagerAware, LogoutAware

   abstract   CachingRealm

   abstract class AuthenticatingRealm
     abstract class AuthorizingRealm

 

先分析doSingleRealmAuthentication(realms.iterator().next(), authenticationToken);

protected AuthenticationInfo doSingleRealmAuthentication(Realm realm, AuthenticationToken token) {

        if (!realm.supports(token)) {
          
            throw new UnsupportedTokenException(msg);
        }
        AuthenticationInfo info = realm.getAuthenticationInfo(token);
        if (info == null) {
           
            throw new UnknownAccountException(msg);
        }
        return info;
    }

所以看到了吧,只要继承  AuthorizingRealm 类,实现里面的getAuthenticationInfo就可以了。

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值