译者:刘晓日

Apache Shiro设计理念是用直观、简单的方式来保证应用的安全。

软件设计通常是基于用户故事来实现的,也就是会根据用户如何与系统交互来设计用户接口或者服务API。比如这样一个用户故事,用户登录后会显示一个查看个人账户信息的按钮,如果用户未注册,则显示一个注册按钮。

这个用户故事暗含了应用主要应完成的用户需求。即使这里的用户不是人而是第三方系统,在编码时也同样当做与系统交互的“用户”来处理。

Apache Shiro的这种理念反应在自己的设计中,通过将直观的概念暴露给开发人员,使得Apache Shiro在几乎所有的应用中都易于使用。

概述

Shiro有三个主要的顶级概念:Subject、SecurityManager、Realms。下图描述了这几个概念之间的交互,下面也将一一做介绍。

enter image description here

  • Subject:Subject是当前用户在安全领域的一个缩影。User通常暗含人的意思,而Subject可以是人,可以是第三方服务,守护账户,corn作业。或者说是任何与系统交互的都可以叫做Subject。 所有的Subject实例都必须绑定到一个SecurityManager,这样当与Subject交互时,其实已经转化成与这个Subject相关联的SecurityManager进行交互。
  • SecurityManager:SecurityManager作为Shiro框架的核心,作为“保护伞”对象的形式存在,它协调其内部安全组件形成一个对象图。当在应用中完成SecurityManager和其内部对象的配置后,SecurityManager就退居二线,开发人员大部分时间都是在使用Subject的API。 随后会深入讲解SecurityManager,再次强调:当与Subject交互时,实际上是隐藏其背后的SecurityManager负责Subject繁重的安全操作。这点在上面的图中也有所体现。
  • Realms:Realms作为Shiro和应用中安全数据源之间的桥梁或者连接器。当需要获取用户账户进行认证(登陆)或授权(访问控制)时,Shiro就会在应用的配置中查找负责这项工作的Realm(一个或多个)来完成获取安全数据。 从这点上讲,Realm实质上就是一个与安全相关的Dao:它封装了数据源链接的详情,并根据Shiro的需要为其提供数据。配置Shiro时,要为认证和授权至少提供一个Reaml。可配置多个Realm,但是至少需要一个。 Shiro内置了可以连接大量安全数据源的Realm,如LDAP、关系数据库(JDBC)、类似INI的文本配置资源以及属性文件等。如果内置的Realm不能满足需求,你还可以使用代表自定义数据源的自己的Realm实现。 和其他内部组件一样,SecurityManager管理Realm如何获取与Subject相关的安全和身份信息。

框架详解

下图展现了Shiro框架的核心概念,随后会一一对其作出简短说明:

enter image description here

Subject(org.apache.shiro.subject.Subject )

安全领域中用户的缩影,可以是人,第三方服务,corn作业等,负责与系统交互。

SecurityManager(org.apache.shiro.mgt.SecurityManager)

就像上文提到的,SecurityManager是Shiro框架的核心。它充当“保护伞”对象的作用,内部协调各个组件,以确保它们顺利开展工作,而且还负责管理Subject,这样它也就获悉了每个Subject怎么执行安全操作了。

Authenticator(org.apache.shiro.authc.Authenticator)

Authenticator负责发出和处理用户的认证请求。当用户登录时,Authenticator负责处理登录逻辑。Authenticator可通过一个或多个Realm获取用户信息,这些信息用来验证当前用户身份。

验证策略(org.apache.shiro.authc.pam.AuthenticationStrategy)

如果配置了多个Realm,就需要AuthenticationStrategy协调Realms来决定在什么样的情况下一个认证的是成功的或失败的。(比如,一个realm认证成功,其他失败,那认证是否通过呢?)

Authorizer (org.apache.shiro.authz.Authorizer)

Authorizer负责应用中用户的访问控制。它是决定用户是否可以在应用中进行某件事的机制。和Authenticator一样,Authorizer可以通过Realm获取角色和权限信息,这样Authorizer就可以确切的知道是否允许用户完成其预期的操作。

SessionManager (org.apache.shiro.session.mgt.SessionManager)

SessionManager用来创建和管理用户Session的生命周期,在任何应用环境下,都可以为用户提供稳定的Session。Shiro可以在任何应用环境下管理用户Session,不需要依附于WEB/Servlet或者EJB容器,这个特性在安全框架领域是唯一的。比如在Servlet容器环境下,默认使用容器自带的Session,如果像在独立应用或非web容器环境下,根本就没有session的存在,那么Shiro使用其内置的企业会话管理器提供同样的编程体验。SessionDao的存在使得任何数据源都可以用来持久session。

SessionDAO (org.apache.shiro.session.mgt.eis.SessionDAO)

SessionDao为SecurityManager提供会话持久(CRUD)功能,这样就可让任何数据源参与到会话管理基础设施中来。

CacheManager (org.apache.shiro.cache.CacheManager)

CacheManager为Shiro的其他组件提供创建缓存实例和管理缓存生命周期的功能。因为Shiro的认证、授权、会话管理支持多种数据源,所以访问数据源时,使用缓存来提高访问效率是上乘的选择。当下主流开源或企业级缓存框架都可以继承到Shiro中,来获取更快更高效的用户体验。

Cryptography (org.apache.shiro.crypto.*)

Cryptography是企业级安全框架基本特征。Shiro的加密包中,包含了易于使用和理解的密码加密,哈希和其他不同加密算法的实现。加密包下面的所有类都是经过精心设计的,来达到易于使用和理解的目的,之前使用过Java自带的加密API的会了解到,它是很难使用的。Shiro的加密API简化了Java复杂的加密机制,而且很容易使用。

Realms(org.apache.shiro.realm.Realm)

上文中也提到过,Realms作为Shiro和应用中安全数据源之间的桥梁或者连接器。当需要获取用户账户进行认证(登陆)或授权(访问控制)时,Shiro就会在应用的配置中查找负责这项工作的Realm(一个或多个)来完成获取安全数据。可以配置多个Realm,大多情况是一个数据源一个Realm,Shiro会负责为认证和授权协调多个Realm一同工作。

SecurityManager简介

由于Shiro采用以Subject为中心的编程方式,所以几乎很少有机会直接与SecurityManager打交道(但与SecurityManager打交道对框架开发人员很重要),尽管如此,了解SecurityManager的作用也还是很重要的,为应用配置SecurityManager的时候尤为重要。

设计

如上文所述,SecurityManager负责处理应用中的安全操作,管理所有应用用户的状态。Shiro中SecurityManager的默认实现包括如下:

  • Authentication
  • Authorization
  • Session Management
  • Cache Management
  • Realm coordination
  • Event propagation
  • "Remember Me" Services
  • Subject creation
  • Logout

等等。

但是让一个组件完成这么多功能,而且做到灵活可定制是非常困难的。为了简化配置和使配置更灵活,Shiro的各种实现采用了高度的模块化。模块化之后,SecurityManager实际上就作为一个轻量级“容器”,几乎所有的功能都委托给内部或包装组件实现。这种包装的设计方法在详细的框架图中也有所体现。

这些组件才是真正的功能实现者,SecurityManager知道如何以及何时协调这些组件做正确的事情即可。

原文链接:http://shiro.apache.org/architecture.html