shiro身份认证流程

首先要理解两个概念:Subject和Realm,分别是主体及验证主体的数据源。web

身份验证步骤以下:数据库

一、收集用户身份/凭证,即如用户名/密码。apache

(1)web项目配置web.xml,再经过如下语句便可得到用户身份/凭证。spa

Subject subject = SecurityUtils.getSubject();

(2)非web项目则获取用户身份/凭证以下:code

//一、获取SecurityManager工厂,此处使用Ini配置文件初始化SecurityManager
        Factory<org.apache.shiro.mgt.SecurityManager> factory =
          new IniSecurityManagerFactory("classpath:shiro.ini");
        //二、获得SecurityManager实例 并绑定给SecurityUtils
        org.apache.shiro.mgt.SecurityManager securityManager = factory.getInstance();
        SecurityUtils.setSecurityManager(securityManager);
        //三、获得Subject及建立用户名/密码身份验证Token(即用户身份/凭证)
        Subject subject = SecurityUtils.getSubject();

二、调用Subject.login进行登陆,若是失败将获得相应的AuthenticationException异常,根据异常提示用户错误信息;不然登陆成功。xml

输入图片说明

(1)调用Subject.login(token)进行登陆,这里的token是须要与数据源进行验证的身份及凭证,调用的login方法是Subject接口的实现类DelegatingSubject里的方法,这个方法又委托给接口SecurityManage, SecurityManage经过实现类DefaultSecurityManager的login方法实现。到这里,咱们知道这个login方法实际执行的是DefaultSecurityManager的login方法。继承

(2)须要验证的数据取到了,那么问题来了,如今怎么与数据库里或.Ini文件里的正确身份/凭证进行验证呢。token

DefaultSecurityManager类的login方法调用了authenticate方法,这个方法来源有点复杂。首先、DefaultSecurityManager经过层层继承,最后继承了抽象类AuthenticatingSecurityManager。如图:接口

输入图片说明

AuthenticatingSecurityManager实现了Authenticator,Authenticator有个实现类叫作AbstractAuthenticator,以下图。图片

输入图片说明

因此咱们AuthenticatingSecurityManager调用的authenticate方法实现实际来源于AbstractAuthenticator,如图:

输入图片说明

AbstractAuthenticator继续调用ModularRealmAuthenticator里的方法doAuthenticate,可进行多Realm身份验证,如图,

输入图片说明

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

最后doMultiRealmAuthentication调用了咱们以前实现的Realm里的getAuthenticationInfo方法,Authenticator会把相应的token传入Realm,从Realm获取身份验证信息,若是没有返回/抛出异常表示身份验证失败了。此处能够配置多个Realm,将按照相应的顺序及策略进行访问

三、最后调用Subject.logout进行退出操做。

相关文章
相关标签/搜索