360SDN.COM

首页/Java/列表

shiro身份认证流程

来源:xiaojujuan  2017-09-11 12:23:13    评论:0点击:

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

身份验证步骤如下:

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

(1)web项目配置web.xml,再通过以下语句即可获得用户身份/凭证。

Subject subject = SecurityUtils.getSubject();

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

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

2、调用Subject.login进行登录,如果失败将得到相应的AuthenticationException异常,根据异常提示用户错误信息;否则登录成功。

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

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

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,将按照相应的顺序及策略进行访问

3、最后调用Subject.logout进行退出操作。

阅读原文

为您推荐

友情链接 |九搜汽车网 |手机ok生活信息网|ok生活信息网|ok微生活
 Powered by www.360SDN.COM   京ICP备11022651号-4 © 2012-2016 版权