Apache Shiro架构
Apache Shiro的设计目标是通过直观和易用来简化应用程序安全性。Shiro的核心设计模拟了大多数人对应用程序安全性的看法 - 在上下文中某人(或某事)与应用程序的交互。
软件应用程序通常基于用户需求设计。也就是说,您通常会根据用户如何与软件交互来设计用户界面或服务API。例如,您可能会说,“如果用户与应用程序是通过登录来交互,那么你会向他们显示一个按钮,他们可以单击该按钮查看其帐户信息。如果他们没有登录,我会显示一个注册按钮。“
此示例语句指示应用程序主要是为满足用户要求和需求而编写的。即使“用户”是另一个软件系统而不是人类,您仍然会编写代码来对当前与您的应用做交互的行为作出反馈。
Shiro在自己的设计中反映了这些概念。通过匹配软件开发人员默认的安全性的概念,Apache Shiro在任何应用程序中都保持直观且易于使用。
一、高级概述
在最高概念层面,Shiro的架构有三个主要概念:和Subject,SecurityManager和Realms。下图是这些组件如何交互的高级概述,我们将在下面介绍每个概念:
1、Subject: 正如我们在之前的示例中提到的,Subject它本质上是当前正在执行的用户的特定于安全性的“视图”。虽然“用户”这个词通常意味着一个人,但是它可以是一个人,但它也可以代表第三方服务,守护进程帐户,定时任务或任何类似的东西 ,总之,它可基本上以是任何与软件交互的东西。
Subject实例都绑定(并要求)到 SecurityManager。当您与一个Subject进行交互时,最后都会转换为与 SecurityManager的交互。
2、SecurityManager: SecurityManager是Shiro架构的核心,充当一种“综合的”对象,协调其内部安全组件。但是,一旦为应用程序配置好了SecurityManager及其内部组件对象,它通常不会再被开发人员调用,应用程序开发人员几乎将所有时间花在Subject的API上。
我们稍后将SecurityManager详细讨论。但目前最重要的要意识到,当您与Subject进行交互时,实际上在幕后是SecurityManager完成所有Subject安全操作。这反映在上面的基本流程图中。
3、Realms: 领域充当Shiro与应用程序安全数据之间的“桥梁”或“连接器”。当实际与安全相关的数据(如用户帐户)进行交互,以执行身份验证(登录)和授权(访问控制)时,Shiro会从为应用程序配置的一个或多个Realm中查找许多这些程序的安全数据。
从这个意义上讲,Realm本质上是一个特定于安全性的DAO:它封装了数据源的连接细节,并组织相关数据,使其满足shiro的需要。配置Shiro时,必须至少指定一个Realm用于身份验证和/或授权。SecurityManager可配置多个Realm,但必须至少有一个。
Shiro提供了开箱即用的Realm,可以连接到许多安全数据源,如LDAP,关系数据库(JDBC),文本配置源(如INI和属性文件等)。如果默认Realm不符合您的需要,您可以用自己的Realm实现来表示自定义数据源。
与其他内部组件一样,Shiro SecurityManager管理如何使用Realms获取要表示为Subject实例的安全且代表身份的数据
二、详细的架构
下图显示了Shiro的核心架构概念,后面是每个概述的简短摘要:
1、Subject(org.apache.shiro.subject.Subject)
当前与软件交互的实体(用户,第三方服务,定时任务等)的特定于安全性的“视图”。
2、SecurityManager(org.apache.shiro.mgt.SecurityManager)
如上所述,这SecurityManager是Shiro架构的核心。它主要是一个“综合”对象,它协调其内部组件以确保它们一起平稳运行。它还管理Shiro对每个应用程序用户的视图,因此它知道如何对每个用户执行安全操作。
3、Authenticator(org.apache.shiro.authc.Authenticator)Authenticator负责对用户企图进行登录进行执行和验证的组件。当用户尝试登录时,由Authenticator执行该逻辑。Authenticator知道如何协调存储有关用户/帐户信息的Realms。从这些Realms中的数据去验证用户的身份,以保证用户确实是他们所说的人。
Authentication Strategy(org.apache.shiro.authc.pam.AuthenticationStrategy)
如果Realm配置了多个,AuthenticationStrategy将协调Realm以确定身份验证尝试成功或失败的条件(例如,如果一个领域成功但其他领域失败尝试成功吗?必须所有领域都成功吗?只有第一个?)。
4、Authorizer(org.apache.shiro.authz.Authorizer)Authorizer是部件负责确定用户在该应用程序的访问控制。这种机制最终会说明是否允许用户做某事。与Authenticator类似,它Authorizer也知道如何协调多个后端数据源以访问角色和权限信息。在Authorizer使用该信息来确定到底是否允许用户执行特定的操作。
5、SessionManager(org.apache.shiro.session.mgt.SessionManager)SessionManager知道如何创建和管理用户Session生命周期,为用户在所有环境中提供一个强大的会话体验。这是shiro在安全框架领域中的一项独特功能 - 即使没有可用的Web / Servlet或EJB容器,Shiro也能够在任何环境中本地管理用户会话。默认情况下,Shiro将使用现有的会话机制(例如Servlet Container),但如果没有,例如在独立应用程序或非Web环境中,它将使用其内置的企业会话管理提供相同的编程。SessionDAO是为了允许持久化session在任何数据源中。
SessionDAO(org.apache.shiro.session.mgt.eis.SessionDAO)SessionDAO代表SessionManager执行Session的持久性(CRUD)操作。这允许将任何数据存储插入会话管理基础结构。
6、CacheManager(org.apache.shiro.cache.CacheManager)CacheManager创建和管理缓存实例生命周期,来被其他组件使用。由于Shiro可以访问许多后端数据源以进行身份验证,授权和会话管理,因此缓存一直是框架中的一流架构功能,可在使用这些数据源时提高性能。任何现代开源或缓存产品都可以应用在Shiro,以提供快速有效的用户体验。
7、Cryptography(org.apache.shiro.crypto.*)
通常而言对Shiro 的 Cryptography 的理解应在于Shiro 提供了一个用于加密解密工具包,相较于JAVA本生机制里面的加密解密而言,Shiro 的 Cryptography更为简单高效同时也很安全。Shiro提供了base64和16进制字符串编码/解码的API支持,方便一些编码解码操作。
8、Realms (org.apache.shiro.realm.Realm)
如上所述,Realms充当Shiro和应用程序安全数据之间的“桥接”或“连接器”。当实际与安全相关的数据(如用户帐户)进行交互以执行身份验证(登录)和授权(访问控制)时,Shiro会从为应用程序配置的一个或多个领域中查找许多这些内容。您可以根据Realms需要配置任意数量(通常每个数据源一个),Shiro将根据需要进行身份验证和授权协调。
SecurityManager
因为Shiro的API鼓励采用Subject为中心编程的方法,所以大多数应用程序开发人员很少,甚至从没直接与SecurityManager进行交互(框架开发人员有时可能会发现它很有用)。即便如此,了解SecurityManager的功能仍然很重要,尤其是在为应用程序配置功能时。
如前所述,应用程序SecurityManager执行安全操作并管理所有应用程序用户的状态。在Shiro的默认SecurityManager实现中,这包括:
- 认证
- 授权
- 会话管理
- 缓存管理
- Realm协调
- 事件传播
- “记住我”服务
- Subject创作
- 退出等等。
但是,有太多功能需要在SecurityManager这个组件中尝试去管理了,并且,如果将所有内容集中到单个实现类中,那么使这些内容变得灵活且可自定义将非常困难。
为了简化配置并实现灵活的配置/可插拔性,Shiro的实现都是高度模块化的设计 。 如此的高度模块化以致于SecurityManager实现(及其类层次结构)根本不处理一点东西。相反,这些SecurityManager实现主要充当轻量级“容器”组件,几乎将所有行为委托给嵌套/包装组件。这种“包装”设计反映在上面的详细架构图中。
当组件实际执行逻辑时,SecurityManager实现知道如何以及何时协调组件以获得正确的行为。
SecurityManager实现和组件也与JavaBeans的兼容,它允许你能够容易地通过标准的JavaBeans的(get,set)方法自定义组件。这意味着Shiro的架构模块化可以转化为非常容易的自定义行为配置。