第一章,认识几个Shiro框架中的关键词
前言:
本文基于Shiro1.4.0
本文将从Shiro的授权和认证的流程和原理直接讲起,不去讲Shiro怎么使用,可能有同学好奇,一般博客或者帖子都是先讲入门使用,然后再去分析原理,但是,笔者这次恰恰相反,因为现在网上关于Shiro的入门使用的帖子或者视频太多太多,不乏有一些比较好的文章,所以萌新同学可以先通过一些其他的帖子进行一个简单入门。不过,值得一说的是,本文在后面的章节也会列举一些Shiro的一些使用方法,比如像:无状态、前后端分离时的项目中如何去使用Shiro的一些建议和方法。本次分享也仅仅是笔者和大家的一个分享学习,文中有错误之处还往同学们能够指出。最后推荐一些Shiro入门的教程,如下:(当然后好的文章推荐请各位同学留言,笔者也会添加到如下推荐中)
1,张开涛老师的《跟我学Shiro系列》
首先,在简析Shiro原理之前,需要先解释几个名词和Shiro中的几个关键对象。
都知道Shiro的权限控制是分为认证和授权的,认证指的是判断当前用户在进行访问时,是否已经登陆过。授权指的是当前用户在访问和操作某一个资源时,是否对这个资源有权限,比如是否可读、可写等。
其次,相信上面这张图片大家在学习Shiro时肯定看见过。如图,应用程序和Shiro直接交互的对象是Subject。下面简单介绍一下图中几个对象的含义和作用。
1,Subject:字面意思是“主题”,它在Shiro中代表了一个当前用户,当然这个用户不单单是指是具体的人。自身是一个接口Interface,包含了几个抽象方法,比如:登陆login()、登出logout()、指定身份runAs()、getPrincipals()等等。个人理解它的作用是在Shiro工作流程中保存当前登陆“用户”的一些身份信息以及登录状态以及其他信息,从而在程序的不同阶段都能够便捷获取当前用户的信息用以其他操作。
2,SecurityManager:字面意思是“安全管理器”,它在Shiro还真的是一个安全管理器,它作为是一个真正执行Subject一些操作的执行者,如下图,Subject的登陆和登出以及创建一个新的Subject均由它完成
3,Realm 字面意思是“领域”,它在Shiro就比较好理解了,它是Shiro留给使用者一个用来和Shiro内部交互的桥梁。使用者可以通过Realm去给Shiro传递一些授权和认证需要的一些数据,从而使Shiro按照我们预期的控制方式去工作。因为Shiro自身是不实现任何权限和用户角色的设计,所以这个接口是我们设计权限系统并交给Shiro去执行的重要接口。
到此,图中的几个对象已经解释完毕,有的同学可能在某些帖子中看到过说这三个对象是Shiro中最重要的组件,我个人觉得这句话说的不完善,如果从外部使用者角度来看,它们三个确实是最重要的组件,Subject提供了当前用户和程序交互的接口,SecurityManager作为Subject与程序交互的实际执行者和管理者,Realm提供了使用者的权限系统数据传递到Shiro中去的桥梁。但是,从原理来说,它们三个只能说是最重要的组件之一。个人觉得就从原理角度来讲,PrincipalCollection这个接口才是最重要的,具体为什么,在你了解完Shiro大体原理后就会有体会。
回过头,说一说再具体Subject这个接口,作为一个接口,肯定不会去直接使用它,在Shiro,Subject主要有以下几个实现类:WebSubject,DelegatingSubject,WebDelegatingSubject,关系如下:
其中WebSubject就是Subject对web项目的一些支持或者说扩展,而DelegatingSubject就比较重要了,它作为Subject的具体实现类,不仅实现了Subject中的抽象方法,同时还有多了一些属性,比如:前面我们说到从使用角度看比较重要的SecurityManager以及从原理角度看最重要的PrincipalCollection以及判断是否登陆的authenticated,主机名host,session等,如图
而WebDelegatingSubject则分别实现和继承了WebSubject和DelegatingSubject,所以它具有两者的功能和属性,在web环境中,我们使用的也是WebDelegatingSubject这个类,后会在源码中看到。
接着在具体聊聊SecurityManager。同样的套路,它是一个接口,肯定不是直接去使用,肯定有实现类,所以直接上族谱图:
它的每个实现类通过名字来看其实也能猜出来它是做什么的
- CachingSecurityManager:缓存的安全管理。Shiro的第一个PrincipalCollection实现类,提供了对缓存的支持
- RealmSecurityManager:域的安全管理。Shiro支持多个Realm的认证策略
- AuthenticatingSecurityManager:认证相关的安全管理器。如登陆、身份验证
- AuthorizingSecurityManager:授权相关的安全管理器。如果判断是否有某个角色,某种权限
- SessionsSecurityManager:Session相关的安全管理器
- DefaultSecurityManager:默认的安全管理器
- WebSecurityManager:添加了在Web中使用SecurityManager的支持
- DefaultWebSecurityManager:Web环境下默认的安全管理器
最后便是Realm。同样的玩法,如下图:
Realm之大概介绍几个它的实现类,其他的有需要的同学可以自行学习。
- CachingRealm:同样,Realm也支持缓存。
- AuthenticatingRealm:认证相关的域,含有一个认证的抽象方法
- AuthorizingRealm:授权相关的域,含有一个授权的抽象方法。这个也是一般我们自定义域是需要继承并重写认证和授权方法的一个域。
- JdbcRealm:Shiro默认的域。一般在使用shiro.ini文件来完成权限控制时,便是这个域在起作用,它内部封装了一些SQL语句用来授权和认证。
以上,便是从外部来看几个重要组件的简介,下面从使用和原理方面讲讲其他的一些接口和类的简介。
1,AuthenticationInfo:身份验证的信息。作为在身份认证时,记录认证信息和结果,可以这么理解,就是在登陆时,登陆成功后承载身份信息的载体,常用实现类SimpleAuthenticationInfo。
2,AuthorizationInfo:授权验证的信息。同AuthenticationInfo类似,只不过它承载的是权限信息,常用实现类SimpleAuthorizationInfo。
3,AuthenticationToken:认证令牌。用来承载认证所需要的参数的载体。常用实现类UsernamePasswordToken等。
4,PrincipalCollection:身份集合。先理解Principal,它代表了对一个Realm的认证校验通过后的身份象征,一个realm会产生一个或者多个Principal(这个由使用者控制,在后续文章中会介绍)。因为Shiro支持多个Realm的,所以一个或者多个Principal,标志着当前用户通过了某一个Realm的校验。然后再来理解PrincipalCollection就不难了,无非就是通过一个或者多个Realm校验后的Principal的集合。为什么之前会说它很重要,因为在进行权限校验时,先会判断当前用户是否有Principal,只有当登陆后的用户才会有Principal,所以如果未登录,Principal为空,默认的将会将请求转发到登陆页面。
OK,Shiro的几个关键词和重要的类和接口基本介绍完了,还有一些接口和类,我们在后面的文章中,随着源码去一步一步探索原理时,再去交流。