Shiro的设计目标是简化应用的安全管理工作。软件通常是以用户为基础设计的。也就是说,我们经常是根据用户是怎样和我们的软件交互的来设计相关的用户接口。比如,你可能会说“如果是已经登录的用户与我的软件交互,那么我给他就显示一个按钮,让他点击后可以查看自己的账户信息。如果用户没有登录,那么我就显示一个注册按钮”。
这个例子说明了我们软件中很多代码都是为了满足用户需求而写。即使“用户”有时候压根就不是一个人(比如说另一个软件系统)。
Shiro的设计反映了这些思想,这样使得开发者更加容易理解Shiro中的一些概念,也使得Shiro更加易用。
一、概览Shiro结构
从高层次来看,Shiro的结构中有三个主要的概念:Subject、SecurityManager和Realms。下图展示了这些组件是如何交互的:
- Subject:指当前正在执行程序的“用户”。Subject含义更广,因为用户通常是指人,而Subject可以指人、进程、计划任务、守护进程等。准确的说,Subject指的是“当前和软件交互的事物”。在多数场景中,你可以将Subject粗暴地认为是用户。
Subject对象都会和一个SecurityManager对象绑定。当你和一个Subject交互时,这些交互行为会被相应的SecurityManager翻译为subject-specific的行为。 - SecurityManager:SecurityManager是Shiro结构中的核心。它用来协调其内部的各种安全组件。然而,一旦SecurityManager和其内部的安全组件配置完成后,程序员就不再会用到它了,这时候程序员通常是与Subject的API打交道。
我们将在后序教程中详细介绍SecurityManager。但是在此之前,要知道当我们与Subject交互时,实际上是SecurityManager在幕后帮我们完成了那些操作,从上面的图中也可以看出这一点。 - Realms:Realms就像一个桥或连接器,将Shiro和你的应用安全数据连接起来。当我们用安全相关的数据交互时,比如用户账户的身份验证(登录)和授权管理,Shiro会从一个或多个配置好的Realms中寻找相关数据。
从这个角度来说,Realms实际上是一个DAO:将连接到数据源的细节封装到内部,并且使Shiro可以轻易地读取相关的数据。当我们配置Shiro时,必须至少有一个Realms。SecurityManager可以由多个Realms配置,但至少有一个Realms配置。
Shiro提供了多种Realms去连接数据源,如LDAP,数据库(JDBC),文本配置文件(如INI)。
和其他内部组件一样,SecurityManager管理Realms如何获取安全数据和认证数据去配置Subject。
二、详细结构
下图展示了Shiro的详细结构:
- Subject:如上文所述。
- SecurityManager:如上文所述。
- Authenticator(认证器):Authenticator是一个负责执行用户登录并对此做出相应动作的内部组件。当用户尝试登录时,逻辑上是Authenticator在执行这个动作。Authenticator知道如何协调一个或多个存储了用户/账户信息的Realms。从Realms获取的信息被用了认证用户身份。
Authentication Strategy是指当有多个Realms时,如果一个Realms登录成功了,然而其他的Realms登录失败了,那么本次登录是成功的还是失败的?这由Authentication Stratege决定。 - Authorizer(核准器):Authorizer是一个负责权限控制的组件。和Authenticator类似,Authorizer知道如何协调一个或多个存储了角色和许可的数据源。Authorizer用这些信息决定用户是否允许做某一动作。
- SessionManager(会话管理):SessionManager知道如何创建并管理一个用户Session。这个特性是其他安全管理框架所不具有的。无论任何环境,Shiro都可以在本地管理Session,即使没有web/servlet或EJB容器。SessionDAO可以管理使用何种数据源去实现Session。
- CacheManager(缓存管理):CacheManager创建并管理Cache对象的生命周期。因为Shiro要访问很多底层的数据源进行身份认证、权限管理和Session管理的操作,所以缓存处于最底层用以提高性能。任何开源的缓存框架都可以集成到Shiro中。
- Cryptography (加密):Shiro的crypro包包含了很多易用的加密算法。
- Realms:如前文所述。
三、The SecurityManager
因为Shior鼓励程序员以Subject为中心开发应用,所以程序员几乎不会和SecurityManager打交道。即便如此,深入地了解一下SecurityManager还是很有必要的。
如前文所述,SecurityManager处理安全操作、管理所有用户的状态,在Shiro默认的SecurityManager中包括下述功能:
- Authentication
- Authoriztion
- Session Managerment
- Cache Managerment
- Realm coordination
- Event propagation(事件传播)
- “记住我”服务
- 创建Subject
- 登出等
为了简化配置并且增强拓展性,Shiro的所有设计都是非常模块化的。如前面详细结构中所叙述的,Shiro将这些复杂的工作设计成了一个又一个模块,而并非完全由SecurityManager完成。
SecurityManager还兼容了JavaBeans,这就允许你通过JavaBeans的accessor/mutator(get/set)自定义这些组件,用JavaBeans风格的配置(如Spring、Guice、JBoss)去配置SecurityManager将会非常简单。我们将在后续教程中做详细介绍。