debug代码解析shiro认证流程

debug代码解析shiro认证流程的示例代码https://gitee.com/158cosmos/springboot_shiro.git

Apache Shiro™是一个优秀的开源权限控制框架,首先看一下官网的框架架构图以及对它的介绍


介绍:
Apache Shiro™ is a powerful and easy-to-use Java security framework that performs authentication, authorization, cryptography, and session management. With Shiro’s easy-to-understand API, you can quickly and easily secure any application – from the smallest mobile applications to the largest web and enterprise applications.
其中shiro最主要的几个组件都在图中:authenticator(认证器),authorizer(授权器),sessionManager(session管理器),cacheManager(缓存管理器),cryptography(加密),sessionDao,Reamls,除了cryptography以外其他的组件都在securityManager中,securityManager是shiro的核心,所有的组件都应依靠它来调用,shiro使用机制-策略的设计模式,所有的组件都可以拔插,可以灵活的替换到自己的实现,用来实现用户自己策略


debug代码解析shiro的工作机制,如何调用到我们注册的realms,执行我们的认证策略,前提条件是我们已经熟悉的shiro的简单使用。
1、第一步,客户端封装usernamePasswordToken,调用login(),这是程序的入口;


2、debug代码追源码,点进login()t源码
解析:
①清除掉现有的凭证
②调用SecurityManager.login(),前面说了SecurityManager是shiro的核心,掌握着认证机制,从而调用到我们的认证策略


3、继续点进SecurityManager.login()


解析:圈红圈的authenticator很眼熟,就是之前架构图的的认证器
4、继续点进认证器


解析:圈红圈的Realms也很熟悉,就是我们架构图里的Pluggable realms,可拔插的realms(支持一个或多个),再看下一行,检查一下realms的个数,如果是一个,执行单个认证方法,如果是多个,执行多个认证方法,这里说明一下:如果是多个realms的话必须同时指定认证策略(貌似支持三种认证策略,默认是一个realms认证通过算认证成功,感兴趣可百度),这里我配置了一个realm,亮出配置xml,这里我也配置了认证策略器(冗余,一个realm时不需要配)
5、点进单个realm认证方法
解析:分两步。第一步参数检查,第二步调用realm.getAuthenticationInfo();getAuthenticationInfo()里的第一步获取缓存(这里涉及到架构图里的CacheManager),如果缓存为空执行第二步用户自己的认证策略,第三步如果我们配置了缓存就把它存入缓存,这里我们关注点不在缓存,继续
6、继续点进doGetAuthenticationInfo(),这一步很重要,因为这个方法最终会调用我们自己的代码,这是在配置文件中指定的,由于重写了这个方法,所以基于java多态特性最终会调用到我自己的认证逻辑org\apache\shiro\shiro-core\1.2.5\shiro-core-1.2.5.jar!\org\apache\shiro\realm\AuthenticatingRealm.class
解析:这是一个抽象的方法,生来就是注定要被继承的
点进去看实现,我实现了shiroReaml,并在配置文件中注入进securityManager中,所以shiro最终必须要调用我的reaml,而不会是其他的realm,很强硬。
7、点进实现,调用自己的认证策略
解析:这里的逻辑是从数据库中查询账号,如果存在将密码封装到Info中返回,我们不负责匹配,交给shiro去匹配,这样shiro拥有了前端传来的usernamePasswordToken,数据库查询出的密码,自然可以进行密码匹配(为什么要交给shiro去匹配是因为还涉及到加密匹配的问题,也就是架构图中的cryptography)
8、回退到第五步,倒数第4行,拿到我们返回Info和传入的token匹配,如果匹配失败抛出异常,成功返回Info(这个匹配器也是可以配置的 我们也可以改源码实现我们自己的匹配逻辑和加密策略)
9、继续回退到第三步
解析:这里152行和163行还涉及到一个登录成功和登录失败的监听器,最重要的是第162行的createSubject()方法
解析:将Subject的状态置为认证通过,并把pricipal(凭证)放入Subject。
10、继续回退,回退到我们的调用者,isAutenticated()则会返回true。自此,调用流程跑完 总结: ①看源码的步骤第一步应当是看懂架构图,从总体对框架有个把握,弄懂他的机制,再去看比较细的策略 ②看源码的过程中应当一步一步截图记录下来或者用流程图时序图记录下来,不然很容易跳来跳去最终跳到晕头转向 不足: shiro的web情况下createSubject()和getSubject()也有很多值得追源码的地方,用来维护会话,有时间应彻底看完。