shiro源码理解笔记(入门第一篇)
subject.login(token)
断点debug,追寻执行。
1.DelegatingSubject.java中的login方法,发现了Subject subject=securityManger.login(this,token);
不难理解,真正执行subject.login的是DelegatingSubject中的login,而且底层使用安全管理器securityManager,把token交付给安全管理器。
2.接着,进入securityManager.login(this,token)的底层实现方法。
securityManager.login(this,token)的父类为DefaultsecurityManager.java
中的public subject login(subject subject,AuthenticationToken token)
方法
AuthencationInfo 大致意思为证明配置
AuthencationInfo info,
info=Authenticate(token)为了搞清楚这个Authenticate的方法大致实现,
接着debug,之后便进入了AuthenticatingsecurityManager类,来到了
public AuthenticationInfo Authenticate(AuthenticationToken token),不难理解这个又是个封装类,其中为return this.authenticator.authenticate(token),
追寻它的父类,AbstractAuthenticator类,之中又调用了doAuthenticate(token),进入了ModularRealmAuthenticator类,首先询问arrsertRealmsConfigured(),是否设置了Realm,创建了个Collection集合,专门把realm取出来,存放到集合之中,再套一个判断,如果容器中大小为1,便返回doSingleRealmAuthentication(realms.iterator.next(),authenticationToken),
否则,返回doMultiRealmAuthentication(Realms,authenticationToken),
之中,doSingleRealmAuthentication判断realm是否支持token,
下一步,AuthenticationInfo info=realm.getAuthenticationInfo(token),
跳转到getAuthenticationInfo的实现类,为AuthenticatingRealm类,在getAuthenticationInfo方法中,有一条AuthenticationInfo info=getCachedAuthenticationInfo(token);从缓存管理器中获取认证信息,
info=doGetAuthenticationInfo(token),点击进入doGetAuthenticationInfo的实现类,SimpleAccountRealm类,把token取出来,强转为UsernamePasswordToken对象,再把UsernamePasswordToken的getuser(),把里面的username传给SimpleAccount对象,把username返回过来,当了一次中间传递,从shiro.ini中查找[users]键对应的值,进行对比校验并重新返回回来,实际上,身份账号校验到这里就结束了。
在SimpleAccountRealm类继续下一步,对SimpleAccount对象进行判断是否为空,这里正常情况都是不为空,接着会判断是否对象有加锁,当然,我们没有,下一步就判断密码是否过期,过期则抛出异常。(ExpriedCredentialsException)
而密码匹配,则在AuthenticatingRealm实现,调用assertCredentialsMatch(),而assertCredenttialsMatch的方法内容则是进行token拆分,再进行对比,如果密码不一致则抛出异常(IncorrectCredentialsException)
所以,日后,使用shiro进行登陆验证,就使用SimpleAccountRealm中的doGetAuthenticationInfo方法重写,写入数据库代码,便实现了数据库账号密码校验。
大致流程:
账号校验:
DelegatingSubject —(securityManager.login(this,token))–> DefaultsecurityManager --(info=Authenticate(token)) --> AuthenticatingsecurityManager --(return this.authenticator.authenticate(token)) --> AbstractAuthenticator --(doAuthenticate(token))–> ModularRealmAuthenticator --(AuthenticationInfo info=realm.getAuthenticationInfo(token))–>AuthenticatingRealm --(info=doGetAuthenticationInfo(token))–>SimpleAccountRealm