Shiro作为轻量级的权限框架,Shiro的认证流程是怎样的一个过程。
如果没有对Shiro进行了解的话,建议先对Shiro学习笔记(一)学习一下Shiro基本的组
成。
1,几大重要组件解析
1.1,Authenticator认证流程
作为用户认证的关键模块,主要是为了返回AuthenticatorInfo信息。
翻开源码,查找到org.apache.shiro.authc包中,此包主要是用于认证的。
首先查看Authenticator接口发现,此接口类作为ShiroAPI的一个主要切入点之一,主要是验
证时候用于和Realm进行交互,根据提交的AuthenticationToken进行验证,成功之后返回
AuthenticationInfo实例。
上图表面,一般是不直接使用Authenticator实例进行交互,这里使用了实现Authenticator接
口的AbstractAuthenticator抽象类的子类ModularRealmAuthenticator类进行实例化。那么我
们看一下ModularRealmAuthenticator做了什么?
ModularRealmAuthenticator类中方法:
先看ModularRealmAuthenticator类中的构造方法,先注入了authenticationStrategy即认
证策略,看过上一章的小伙伴很清楚,Realm认证主要有四种策略,这里选择的其中一种
AtLeastOneSuccessfulStrategy(至少有一个Realm认证成功的策略)。
也可以通过GetterSetter设置Realm,设置authenticationStrategy等。
剩下的就是最关键的部分认证了,doAuthenticate方法是实现了Authenticator的接口方法,
根据是单Realm方式还是多Realm方式执行不同的实现方法。
现在进入单Realm认证方法看看:
类中先是对于token的类型做了判断,必须为authenticationToken类型才可以。随后通过
realm获取到AuthenticationInfo类,realm自己并不会去实现,上次文章也描述了,Realm具体
实现是由我们自己去实现验证判断的逻辑,Realm接口继承关系为:
Realm-->CachingRealm-->AuthenticatingRealm
-->AuthorizingRealm-->ModularRealmAuthenticator复制代码
下图是自定义Realm:
例如上图中的自定义MyRealm继承了AuthoriziongRealm抽象类,作为最底层子类,只需要实
现doGetAuthenticationInfo方法和doGetAuthorizationInfo方法(此方法下次讲述),之后返回
AuthenticationInfo对象。
realm.getAuthenticationInfo(token);
//等价于调用子类MyRealm中的doGetAuthenticationInfo方法
doGetAuthenticationInfo(token);复制代码
OK至此认证的任务就完成了,返回的AuthenticationInfo对象会传给SecurityManager进行
下一步操作。
1.2 Authorizer授权流程
认证说完了,同时Shiro还需要进行对用户的授权啊,授权和认证的流程非常相似,这里就简
要说一下。
同样的看一下org.apache.shiro.authz包下:
包内的结构和Authenticator很相似,首先看Authorizer这一基础接口,定义了很多我们所需要
的方法,例如是否具备权限,检查权限,检查角色,检查该用户是否具备该角色或者该权限。
其具体的实现类是AuthorizingRealm,AuthorizingRealm类不仅实现了Authorizer的所有方
法,我们在继承的时候只需要实现doGetAuthorizationInfo方法就可以了。
这里我们细致说一下AuthorizingRealm类,首先看类中:
类构造器加载了权限转换器PermissionResolver、缓存Name、密码匹配CredentialsMatcher
其中授权最核心的方法是getAuthorizationInfo,返回一个AuthorizationInfo对象,即完成授权
信息的获取。
上图这一段代码表述为Shiro先从Cache里读取之前是否以及获取过授权信息,首先调用
getAvailableAuthorizationCache()方法获取授权信息的Cache,并且定义authorizationCache
缓存,此缓存由getAuthorizationCacheLazy方法懒加载获取,通过CacheManager中
getCache(authorizationCacheName)获取。
authorizationCacheName在初始化构造时候就以及设定为如下
this.authorizationCacheName = getClass().getName() + DEFAULT_AUTHORIZATION_CACHE_SUFFIX;复制代码
从CacheManager中获取到Cache返回给上层。
如果缓存中没有,则调用doGetAuthorizationInfo()方法进行获取,那么此方法就是我们自己定
义的MyRealm中实现的逻辑。
设置相应的角色和权限集合放置在AuthorizationInfo对象中即可。
OK获取授权信息到此就结束了。
下一次开始讲述核心部件流程SecurityManager。