Shiro身份认证流程

shiro全局设置

1.获取SecurityManager工厂,读取ini文件

Factory<org.apache.shiro.mgt.SecurityManager> factory =new IniSecurityManagerFactory(configFile);

2.通过ini初始化实例,将配置好的的realm注入securityManager实例

org.apache.shiro.mgt.SecurityManager securityManager = factory.getInstance();

调用IniSecurityManagerFactory的createSecurityManager(Ini ini, Section mainSection)方法,调用this.isAutoApplyRealms(securityManager)

private SecurityManager createSecurityManager(Ini ini, Section mainSection) {

Map<String, ?> defaults = this.createDefaults(ini, mainSection);

Map<String, ?> objects = this.buildInstances(mainSection, defaults);

SecurityManager securityManager = this.getSecurityManagerBean();

boolean autoApplyRealms = this.isAutoApplyRealms(securityManager);

if (autoApplyRealms) {

Collection<Realm> realms = this.getRealms(objects);

if (!CollectionUtils.isEmpty(realms)) {

this.applyRealmsToSecurityManager(realms, securityManager);

}

}

return securityManager;

}

调用this.isAutoApplyRealms(securityManager)判断是否自动引入realm,有则继续

无则调用this.applyRealmsToSecurityManager(realms, securityManager);将realm注入securityManager

返回securityManager实例

3.绑定给SecurityUtils

SecurityUtils.setSecurityManager(securityManager);

4.通过 SecurityUtils 得到 Subject,其会自动绑定到当前线程;ThreadContext.bind(subject);

Subject subject = SecurityUtils.getSubject();

5. 应用代码通过 Subject 来进行认证和授权

 

认证:

代码调用

UsernamePasswordToken token = new UsernamePasswordToken("zhang", "123");         

1.subject.login(token);

调用DelegatingSubject的login(AuthenticationToken token)方法进行认证

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

因为Subject不真正执行认证逻辑,又委托给 SecurityManager;

3.info = this.authenticate(token);                

调用DefaultSecurityManager的login(Subject subject, AuthenticationToken token)方法,

4.this.authenticator.authenticate(token);

调用AuthenticatingSecurityManager的authenticate(AuthenticationToken token)方法

5.info = this.doAuthenticate(token);

SecurityManager 不负责真正的身份验证逻辑;它会委托给 Authenticator 进行身份验证;        

调用AbstractAuthenticator的authenticate(AuthenticationToken token)                        

6.Authenticator 才是真正的身份验证者,默认调用ModularRealmAuthenticator的doAuthenticate(AuthenticationToken authenticationToken)方法,

在这个方法里,判断是多Realm认证,还是单Realm认证

protected AuthenticationInfo doAuthenticate(AuthenticationToken authenticationToken) throws AuthenticationException {

this.assertRealmsConfigured();

Collection<Realm> realms = this.getRealms();

return realms.size() == 1 ? this.doSingleRealmAuthentication((Realm)realms.iterator().next(), authenticationToken) : this.doMultiRealmAuthentication(realms, authenticationToken);

}

7.Authenticator 会把相应的 token 传入 Realm

realm.getAuthenticationInfo(token)                        

如果是单realm

1.this.doSingleRealmAuthentication((Realm)realms.iterator().next(), authenticationToken)

2.调用doSingleRealmAuthentication(Realm realm, AuthenticationToken token)

3.AuthenticationInfo info = realm.getAuthenticationInfo(token);

如果是多realm

Authenticator 可能会委托给相应的 AuthenticationStrategy 进行多 Realm 身份验证

调用doMultiRealmAuthentication(Collection<Realm> realms, AuthenticationToken token)

1.AuthenticationInfo aggregate = strategy.beforeAllAttempts(realms, token);

2.Iterator i$ = realms.iterator();

3.while(i$.hasNext()) {

aggregate = strategy.beforeAttempt(realm, token, aggregate);

4.info = realm.getAuthenticationInfo(token);

aggregate = strategy.afterAttempt(realm, token, info, aggregate, t);

}

5.aggregate = strategy.afterAllAttempts(token, aggregate);

8.从 Realm 获取身份验证信息                

调用自定义Realm的doGetAuthenticationInfo(AuthenticationToken token)方法,获取reaml认证需要的信息

Realm里面是真正的验证逻辑

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值