2. Introduction

2.1 什么是 Spring Security?

Spring Security 为基于 Java EE 的企业软件应用程序提供全面的安全服务。特别强调支持使用 The Spring Framework 构建的项目,该框架是用于企业软件开发的领先 Java EE 解决方案。如果您不使用 Spring 开发企业应用程序,我们热烈鼓励您仔细研究它。熟悉 Spring,尤其是依赖注入原理,将帮助您更轻松地掌握 Spring Security。

人们使用 Spring Security 的原因有很多,但是大多数人是在发现 Java EE 的 Servlet 规范或 EJB 规范的安全功能后才被吸引到该项目的,而这些功能缺乏典型企业应用场景所需的深度。在提及这些标准时,重要的是要认识到它们在 WAR 或 EAR 级别上不是可移植的。因此,如果您切换服务器环境,则在新的目标环境中重新配置应用程序的安全性通常需要大量工作。使用 Spring Security 克服了这些问题,还为您带来了许多其他有用的,可自定义的安全功能。

您可能知道应用程序安全性的两个主要方面是“身份验证”和“授权”(或“访问控制”)。这是 Spring Security 的两个主要领域。 “认证”是构建委托人的过程,所谓委托人就是他们所宣称的身份(“主要”通常是指可以在您的应用程序中执行操作的用户,设备或其他系统)。“授权”是指确定的过程是否允许委托人在您的应用程序中执行操作。为了到达需要授权决策的位置,主体的身份已经通过身份验证过程确定。这些概念是通用的,并非完全针对于 Spring Security。

在身份验证级别,Spring Security 支持多种身份验证模型。这些身份验证模型中的大多数要么由第三方提供,要么由相关的标准机构(例如 Internet 工程任务组)开发。另外,Spring Security 提供了自己的一组身份验证功能。具体来说,Spring Security 当前支持与所有以下技术的身份验证集成:

  • HTTP BASIC 身份验证 Headers(基于 IETF RFC 的标准)

  • HTTP 摘要验证 Headers(基于 IETF RFC 的标准)

  • HTTP X.509Client 端证书交换(基于 IETF RFC 的标准)

  • LDAP(一种非常常见的跨平台身份验证方法,特别是在大型环境中)

  • 基于表单的身份验证(用于简单的用户界面需求)

  • OpenID authentication

  • 基于预先构建的请求 Headers 的身份验证(例如 Computer Associates Siteminder)

  • Jasig 中央认证服务(也称为 CAS,这是一种流行的开源单点登录系统)

  • 远程方法调用(RMI)和 HttpInvoker(Spring 远程协议)的透明身份验证上下文传播

  • 自动的“记住我”身份验证(因此您可以在方框中打勾,以避免在 sched 的时间段内进行重新身份验证)

  • 匿名身份验证(允许每个未经身份验证的调用自动采用特定的安全身份)

  • 运行身份验证(如果一个调用应以不同的安全身份进行则很有用)

  • Java 身份验证和授权服务(JAAS)

  • Java EE 容器身份验证(因此,如果需要,您仍然可以使用容器 Management 的身份验证)

  • Kerberos

  • Java 开源单一登录(JOSSO)*

  • OpenNMS 网络 Management 平台*

  • AppFuse *

  • AndroMDA *

  • ule 子 ESB *

  • 直接 Web 请求(DWR)*

  • Grails *

  • Tapestry *

  • JTrac *

  • Jasypt *

  • Roller *

  • 弹性路径*

  • Atlassian 人群*

  • 您自己的身份验证系统(请参见下文)

(*表示由第三方提供

由于选择了灵活的身份验证模型,因此许多独立软件供应商(ISV)都采用了 Spring Security。这样一来,他们就可以快速将解决方案与最终 Client 的需求进行集成,而无需进行大量工程设计或要求 Client 更改环境。如果以上认证机制都不满足您的需求,那么 Spring Security 是一个开放平台,编写您自己的认证机制非常简单。 Spring Security 的许多企业用户需要与不遵循任何特定安全性标准的“旧版”系统集成,Spring Security 乐于在此类系统上“表现出色”。

与身份验证机制无关,Spring Security 提供了一组深层的授权功能。主要涉及三个方面:授权 Web 请求,授权是否可以调用方法以及授权对单个域对象实例的访问。为了帮助您理解差异,请分别考虑 Servlet 规范 Web 模式安全性,EJB 容器 Management 的安全性和文件系统安全性中的授权功能。 Spring Security 在所有这些重要领域中都提供了深层功能,我们将在本参考指南的后面部分中进行探讨。

2.2 History

Spring Security 于 2003 年末开始,称为“ Spring Acegi 安全系统”。在 Spring Developers 的邮件列表上提出了一个问题,询问是否考虑过基于 Spring 的安全性实现。当时 Spring 社区相对较小(尤其是与今天的规模相比!),实际上 Spring 本身只是从 2003 年初开始作为 SourceForge 项目存在的。对此问题的回答是,尽管缺少它,但它是一个值得的领域目前有一段时间阻止了它的探索。

考虑到这一点,构建了一个简单的安全性实施方案,但并未发布。几周后,Spring 社区的另一位成员询问了安全性,并在当时向他们提供了此代码。随后提出了其他一些要求,到 2004 年 1 月,大约有 20 个人正在使用该代码。这些开拓性用户与其他人一起参加了会议,他们建议 OrderSourceForge 项目,该项目于 2004 年 3 月正式成立。

在早期,该项目没有任何自己的身份验证模块。身份验证过程依赖于 Container Managed Security,而 Acegi Security 则专注于授权。起初这是合适的,但是随着越来越多的用户请求附加的容器支持,特定于容器的身份验证领域接口的基本限制变得显而易见。还有一个相关问题,即在容器的 Classpath 中添加新的 JAR,这是导致最终用户混淆和配置错误的常见原因。

随后引入了 Acegi Security 特定的身份验证服务。大约一年后,Acegi Security 成为正式的 Spring Framework 子项目。 1.0.0 最终版本于 2006 年 5 月发布-经过两年半的时间在众多生产软件项目中进行了积极使用,并进行了数百次改进和社区贡献。

Acegi Security 在 2007 年底成为正式的 Spring Portfolio 项目,并更名为“ Spring Security”。

今天,Spring Security 拥有强大而活跃的开源社区。支持论坛上有成千上万条有关 Spring Security 的消息。有一个活跃的开发人员核心从事代码本身的工作,还有一个活跃的社区,该社区也定期共享补丁并为同辈提供支持。

2.3 版本编号

了解 Spring Security 发行版编号的工作方式很有用,因为它将帮助您确定迁移到项目的将来发行版中所涉及的工作(或缺乏工作量)。每个发行版都使用标准的整数三 Tuples:MAJOR.MINOR.PATCH。目的是 MAJOR 版本是不兼容的 API 的大规模升级。 MINOR 版本应在很大程度上保留与较早的次要版本的源代码和二进制兼容性,以为可能会有一些设计更改和不兼容的更新。 PATCH 级别应该是完全兼容的,向前和向后兼容,可能存在的 exception 是为了修复错误和缺陷而进行的更改。

您受更改影响的程度将取决于代码的紧密集成程度。如果您要进行大量的自定义操作,则比使用简单的名称空间配置时,受影响的可能性更大。

在推出新版本之前,应该始终对应用程序进行全面测试。

2.4 获取 Spring Security

您可以通过多种方式获得 Spring Security。您可以从Spring Security主页下载打包的发行版,从 Maven Central 存储库(或用于快照和里程碑版本的 Spring Maven 存储库)下载单个 jar,或者,也可以自己从源代码构建项目。

2.4.1 Maven 的用法

最小的 Spring Security Maven 依赖关系集通常如下所示:

pom.xml.

<dependencies>
<!-- ... other dependency elements ... -->
<dependency>
	<groupId>org.springframework.security</groupId>
	<artifactId>spring-security-web</artifactId>
	<version>4.2.10.RELEASE</version>
</dependency>
<dependency>
	<groupId>org.springframework.security</groupId>
	<artifactId>spring-security-config</artifactId>
	<version>4.2.10.RELEASE</version>
</dependency>
</dependencies>

如果您正在使用 LDAP,OpenID 等其他功能,则还需要包括相应的第 2.4.3 节“项目模块”

Maven Repositories

所有 GA 版本(即以.RELEASE 结尾的版本)均已部署到 Maven Central,因此无需在 pom 中声明其他 Maven 存储库。

如果您使用的是 SNAPSHOT 版本,则需要确保已定义 Spring Snapshot 存储库,如下所示:

pom.xml.

<repositories>
<!-- ... possibly other repository elements ... -->
<repository>
	<id>spring-snapshot</id>
	<name>Spring Snapshot Repository</name>
	<url>http://repo.spring.io/snapshot</url>
</repository>
</repositories>

如果您使用的是里程碑版本或候选版本,则需要确保定义了 Spring Milestone 存储库,如下所示:

pom.xml.

<repositories>
<!-- ... possibly other repository elements ... -->
<repository>
	<id>spring-milestone</id>
	<name>Spring Milestone Repository</name>
	<url>http://repo.spring.io/milestone</url>
</repository>
</repositories>

Spring Framework Bom

Spring Security 是基于 Spring Framework 4.3.21.RELEASE 构建的,但应与 4.0.x 一起使用。许多用户将遇到的问题是 Spring Security 的可传递依赖项解决了 Spring Framework 4.3.21RELEASE,这可能会导致奇怪的 Classpath 问题。

解决该问题的一种(乏味的)方法是将所有 Spring Framework 模块包含在 pom 的<dependencyManagement>部分中。另一种方法是将spring-framework-bom包含在pom.xml<dependencyManagement>部分中,如下所示:

pom.xml.

<dependencyManagement>
	<dependencies>
	<dependency>
		<groupId>org.springframework</groupId>
		<artifactId>spring-framework-bom</artifactId>
		<version>4.3.21.RELEASE</version>
		<type>pom</type>
		<scope>import</scope>
	</dependency>
	</dependencies>
</dependencyManagement>

这将确保 Spring Security 的所有传递依赖项都使用 Spring 4.3.21RELEASE 模块。

Note

此方法使用 Maven 的“物料 Lists”(BOM)概念,并且仅在 Maven 2.0.9 中可用。有关如何解决依赖关系的其他详细信息,请参见Maven 的依赖机制简介文档

2.4.2 Gradle

最小的 Spring Security Gradle 依赖关系集通常如下所示:

build.gradle.

dependencies {
	compile 'org.springframework.security:spring-security-web:4.2.10.RELEASE'
	compile 'org.springframework.security:spring-security-config:4.2.10.RELEASE'
}

如果您正在使用 LDAP,OpenID 等其他功能,则还需要包括相应的第 2.4.3 节“项目模块”

Gradle Repositories

所有 GA 版本(即以.RELEASE 结尾的版本)均已部署到 Maven Central,因此使用 mavenCentral()存储库足以满足 GA 版本的要求。

build.gradle.

repositories {
	mavenCentral()
}

如果您使用的是 SNAPSHOT 版本,则需要确保已定义 Spring Snapshot 存储库,如下所示:

build.gradle.

repositories {
	maven { url 'https://repo.spring.io/snapshot' }
}

如果您使用的是里程碑版本或候选版本,则需要确保定义了 Spring Milestone 存储库,如下所示:

build.gradle.

repositories {
	maven { url 'https://repo.spring.io/milestone' }
}

使用 Spring 4.0.x 和 Gradle

默认情况下,Gradle 在解决传递版本时将使用最新版本。这意味着在运行带有 Spring Framework 4.3.21.RELEASE 的 Spring Security 4.2.10.RELEASE 时,通常不需要其他工作。但是,有时可能会出现问题,因此最好使用Gradle's ResolutionStrategy缓解此问题,如下所示:

build.gradle.

configurations.all {
	resolutionStrategy.eachDependency { DependencyResolveDetails details ->
		if (details.requested.group == 'org.springframework') {
			details.useVersion '4.3.21.RELEASE'
		}
	}
}

这将确保 Spring Security 的所有传递依赖项都使用 Spring 4.3.21RELEASE 模块。

Note

本示例使用 Gradle 1.9,但由于这是 Gradle 中的一个孵化功能,因此可能需要进行修改才能在 Gradle 的 Future 版本中使用。

2.4.3 项目模块

在 Spring Security 3.0 中,代码库已细分为单独的 jar,这些 jar 更清楚地将不同的功能区域和第三方依赖项分开。如果您使用 Maven 来构建项目,那么这些模块将添加到pom.xml中。即使您不使用 Maven,我们也建议您查阅pom.xml文件,以了解第三方依赖性和版本。另外,一个好主意是检查示例应用程序中包含的库。

核心-spring-security-core.jar

包含核心身份验证和访问控制类和接口,远程支持和基本配置 API。使用 Spring Security 的任何应用程序都需要。支持独立的应用程序,远程 Client 端,方法(服务层)安全性和 JDBC 用户配置。包含顶级软件包:

  • org.springframework.security.core

  • org.springframework.security.access

  • org.springframework.security.authentication

  • org.springframework.security.provisioning

远程处理-spring-security-remoting.jar

提供与 Spring Remoting 的集成。除非您正在编写使用 Spring Remoting 的远程 Client 端,否则您不需要这样做。主要包是org.springframework.security.remoting

网络-spring-security-web.jar

包含过滤器和相关的 Web 安全基础结构代码。任何与 servlet API 依赖的东西。如果您需要 Spring Security Web 认证服务和基于 URL 的访问控制,则将需要它。主要包是org.springframework.security.web

配置-spring-security-config.jar

包含安全名称空间解析代码和 Java 配置代码。如果您使用 Spring Security XML 名称空间进行配置或 Spring Security 的 Java 配置支持,则需要它。主要包是org.springframework.security.config。这些类都不打算直接在应用程序中使用。

LDAP-spring-security-ldap.jar

LDAP 身份验证和配置代码。如果您需要使用 LDAP 身份验证或 ManagementLDAP 用户条目,则为必需。顶级软件包是org.springframework.security.ldap

ACL-spring-security-acl.jar

专门的域对象 ACL 实现。用于将安全性应用于应用程序中的特定域对象实例。顶级软件包是org.springframework.security.acls

CAS-spring-security-cas.jar

Spring Security 的 CASClient 端集成。如果您想将 Spring Security Web 认证与 CAS 单一登录服务器一起使用。顶级软件包是org.springframework.security.cas

OpenID-spring-security-openid.jar

OpenID Web 身份验证支持。用于根据外部 OpenID 服务器对用户进行身份验证。 org.springframework.security.openid。需要 OpenID4Java。

测试-spring-security-test.jar

支持使用 Spring Security 进行测试。

2.4.4 签出源

由于 Spring Security 是一个开源项目,因此我们强烈建议您使用 git 签出源代码。这将使您可以完全访问所有示例应用程序,并且可以轻松构建项目的最新版本。拥有项目的源代码也有助于调试。异常堆栈跟踪不再是晦涩难懂的黑匣子问题,但您可以直截了当地找出导致问题的原因并弄清正在发生的事情。来源是项目的最终文档,并且通常是查找某些事物实际工作方式的最简单的地方。

要获取项目的源代码,请使用以下 git 命令:

git clone https://github.com/spring-projects/spring-security.git

这将使您可以访问本地计算机上的整个项目历史记录(包括所有发行版和分支)。