Shiro-token委托过程
2021-11-16 14:36:52 0 举报
Shiro框架下token委托过程流程图以及一些理解困难点解读。
作者其他创作
大纲/内容
DefaultSecurityManager
Y
public static final String DEFAULT_LOGIN_URL = \"/login.jsp\";
ModularRealmAuthenticator
起初,个人认为authenticate()直接放在M.R.A.里更合适,即直接让M.R.A.直接实现Authenticator接口,再继承A.A.,因为抽象类不应该有实体方法。后面仔细一想,所有类型的鉴定器都有鉴定这一方法,鉴定这一方法可以有两种方式获得:1.实现带有鉴定方法的接口,实体化方法;2.继承带有鉴定方法的类,获得方法继承或重写方法。两者区别在于接口只是一种协议,比如Authenticator接口,实现该接口意味着需要实现authenticate()方法,仅此。继承带有鉴定方法的类时对父类的扩展,父类如果实现了Authenticator接口,便是对拥有authenticate()方法的扩展,各类鉴定器有着诸多共同的常见的工作,因此用通用鉴定器去拓展,更符合模块化设计。子类完全可以重写这些工作的处理逻辑,之所以doAuthenticate()定义为抽象方法,是因为A.A. 一定要 委托给子类去实体化,是一种强业务约束。
鉴权信息
[abstract] CachingRealm
自定义Realm
subject.login(token)
被拦截
SecurityManager<interface>
ModularRealmAuthenticator对象的authenticate(token)方法继承自AbstractAuthenticator抽象鉴定器的实体方法,且该方法中调用了ModularRealmAuthenticator类已实体化AbstractAuthenticator类的抽象方法doAuthenticate()执行鉴定业务。(这里描述起来很绕口,实际上,AuthenticatingSecurityManager中实例化的this.authenticator对象是一个继承了AbstractAuthenticator(A.A.)类的ModularRealmAuthenticator(M.R.A.)对象,M.R.A不仅继承了A.A.对象的所有非私密实体方法与属性,还继承了A.A.对象的所有抽象方法,并全部实体化,即M.R.A.对象也拥有A.A.对象非私密的一切,这里并不是委托模式)
[Abstract] AuthenticatingRealm
请求
[Abstract]createToken
assertRealmsConfigured
委托鉴权(token)
SessionsSecurityManager
realm.getAuthenticationInfo(token)
是否登录请求
BasicHttpAuthenticationFilter基础HTTP鉴权过滤器
确认Realm已配置
Subject<接口>委托交互协议
Shiro会确保身份验证的过程一直处于安全协议的情况下。
自定义Filter
验证信息
[Abstract] AuthenticatingFilter
Subject<interface>
DefaultSecurityManager默认安全管理者
DelegatingSuject类实例化时,引入了SecurityManager对象,创建了委托者。执行login方法时,调用securityManager.login执行委托事件login。SecurityManager是一个接口类,构造DelegatingSuject对象时,securityManager作为句柄指向了实现类DefaultSecurityManager。
authenticate(AuthenticationToken token)
为了App访问接口时具有鉴权机制,通常,会设置一个过滤器,拦截app发往服务器的请求,对请求头里保存的信息提取,验证其是否具有访问该路径的权限,如果开发者不想自己完成这个事情,便可以将这个业务委托给Shiro去完成,Shiro鉴权过滤器委托自定义Filter,去创建业务中需要的token,自定义的Filter继承Shiro.AuthenticatingFilter抽象类,返回Token实体。
多态:实际委托鉴权(token)
login(AuthenticationToken token)
this.authenticator = new ModularRealmAuthenticator();
executeLogin
ModularRealmAuthenticator对象构造时,建立了与Realm的委托关系,Realm为接口,作为句柄指向了实现类securityMananger.getRealm(),securityMananger是securityManangerFactory工厂根据securityManangerFactoryBean注入的对象,其中realm为自定义的Realm对象。调用了域身份校验方法,该方法会执行委托事件getAuthenticationInfo(token),通过token获取身份校验信息。
DelegatingSuject
登录信息
[abstract] getAuthenticationInfo(AuthenticationToken token)
[abstract] AbstractAuthenticator
Authenticator<接口>鉴权协议
getRealms()
token
委托登录(token)
SecurityManager<接口>安全管理协议
Realm<接口>领域协议
Realm<interface>
由于loginUrl是静态常量,app的每次请求都将匹配为登录请求,并执行token创建,即计算出token
多态(父类引用指向子类对象)
AuthenticatingSecurityManager
DelegatingSuject对象父类AuthenticatingSecurityManager.authenticate(token)方法返回一个this.authenticator.authenticate(token)方法,即验证安全管理者委托鉴定器完成鉴定业务,鉴定器Authenticator是接口类作为句柄指向了实现类ModularRealmAuthenticator对象,即鉴定器的类型为模块化域身份鉴定器。
FormAuthenticationFilter表单鉴权过滤器
extends
ModularRealmAuthenticator模块化的领域鉴权器
override实体
多态(继承)
doGetAuthenticationInfo
AuthenticatingFilter鉴权过滤器
自定义Filter
[abstract] doAuthenticate(token)
AuthenticatingSecurityManager鉴权安全管理者
Shiro鉴权委托流程
RealmSecurityManager
implements
this.authenticator.authenticate(token)
doAuthenticate(token)
Shiro拦截到请求后,执行登录。委托自定义Filter创建token,AuthenticatingFilter获取到token后,getSubject获取当前Subject对象(获取Subject对象也是一个复杂的过程,暂时不细研究,根据检索,最终发现接口Suject作为句柄实例化了DelegatingSubject对象),AuthenticatingFilter委托DelegatingSubject对象执行login方法。
token (entity)
createToken
Shiro使用过程中,创建的token被用来获取身份验证信息,Filter没有与Realm产生直接关联,却完成了委托,以下过程便是token的委托逻辑。
Authenticator<interface>
FormAuthenticationFilter
多态:实际委托登录(token)
CachingSecurityManager
AuthenticationInfo
委托
AccessControlFilter
自定义Realm安全数据源由此得到了Filter创建的token,此后在Realm中进行安全的数据访问操作
AuthenticationToken
DelegatingSuject面向委托的对象
AuthorizingSecurityManager
Shiro为什么要这样设计一个鉴权过程,为什么说这样的过程代表着数据安全的?
authenticate(token)
委托生产token
BasicHttpAuthenticationFilter
[Abstract] AuthorizingRealm
0 条评论
下一页