Spring Security 7.0 新特性详解
概述
Spring Security 7.0 是一个重要的版本更新,带来了多项新功能、API 改进和安全性增强。本文档详细介绍 Spring Security 7.0 的主要新特性,包括破坏性变更、新增功能以及改进的功能。
版本要求
Spring Security 7.0 的最低版本要求:
- Spring Framework: 6.x 或更高版本
- Spring Boot: 4.0.x (如果使用 Spring Boot)
- Java: 17 或更高版本
- Jakarta EE : Jakarta EE 9+ 命名空间 (使用
jakarta.*替代javax.*)
主要新特性
1. 核心 API 改进
1.1 Authorization Manager API 优化
Spring Security 7.0 移除了 AuthorizationManager#check 方法,全面采用 AuthorizationManager#authorize 方法。
迁移示例:
java
// 6.x 版本
AuthorizationDecision decision = authorizationManager.check(
authentication, object);
// 7.0 版本
AuthorizationDecision decision = authorizationManager.authorize(
authentication, object);
authorize 方法在 Spring Security 5.5 中引入,现在是唯一支持的方法。
1.2 身份验证构建器 (Authentication Builder)
Spring Security 7.0 引入了 Authentication.Builder 用于创建和修改 Authentication 实例。虽然这是新增功能,不需要迁移,但它为自定义身份验证逻辑提供了更简洁的 API。
1.3 访问决策 API 迁移支持
如果应用程序使用传统的访问决策 API (AccessDecisionManager, AccessDecisionVoter),需要添加 spring-security-access 模块:
Maven 配置:
xml
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-access</artifactId>
</dependency>
Gradle 配置:
gradle
implementation 'org.springframework.security:spring-security-access'
这些 API 自 Spring Security 5.5 起已被废弃,现在推荐使用 AuthorizationManager。
2. Web 安全增强
2.1 会话并发控制改进
SessionLimit 函数式接口提供了更灵活的会话控制策略。虽然基于整数的 API 仍然支持,但函数式方法允许为每个用户动态设置会话限制。
简单方式(仍然支持):
java
http.sessionManagement(session -> session
.sessionConcurrency(concurrency -> concurrency
.maximumSessions(1)
.maxSessionsPreventsLogin(true)
)
);
函数式方式(7.0 新特性):
java
http.sessionManagement(session -> session
.sessionConcurrency(concurrency -> concurrency
.maximumSessions(SessionLimit.of(authentication -> {
// 基于用户角色的动态限制
if (hasRole(authentication, "ADMIN")) {
return -1; // 管理员无限制
}
return 1; // 普通用户限制
}))
.maxSessionsPreventsLogin(true)
)
);
2.2 默认登录页面多因素认证支持
默认登录页面现在支持基于 factor.type 和 factor.reason 请求参数显示多因素身份验证提示。这不需要迁移,但提供了增强的功能。
3. SAML 2.0 改进
3.1 注销响应行为
在 Spring Security 7.0 中,当 <saml2:LogoutRequest> 验证失败时,Spring Security 现在返回错误的 <saml2:LogoutResponse> 而不是返回 HTTP 401。这符合 SAML 2.0 规范要求。
3.2 AssertingPartyDetails 移除
AssertingPartyDetails 类已被移除。使用 AssertingPartyMetadata 接口替代。
迁移示例:
java
// 6.x 版本
public void processAssertion(AssertingPartyDetails details) {
String entityId = details.getEntityId();
// ...
}
// 7.0 版本
public void processAssertion(AssertingPartyMetadata metadata) {
String entityId = metadata.getEntityId();
// ...
}
3.3 Saml2AuthenticatedPrincipal 废弃
Spring Security 7.0 将断言详情与主体分离。凭证现在实现 Saml2ResponseAssertionAccessor 而不是使用 Saml2AuthenticatedPrincipal。
默认行为使用 Saml2AssertionAuthentication 自动处理此功能。
3.4 GET 请求支持移除
Saml2AuthenticationTokenConverter 和 OpenSaml5AuthenticationTokenConverter 默认不再处理 GET 请求,因为 SAML 2.0 规范不支持通过 GET 传递 <saml2:Response>。
3.5 OpenSAML 5 要求
移除了 OpenSAML 4 支持。需要迁移到 OpenSAML 5。
Maven 依赖:
xml
<dependency>
<groupId>org.opensaml</groupId>
<artifactId>opensaml-core</artifactId>
<version>5.0.0</version>
</dependency>
<dependency>
<groupId>org.opensaml</groupId>
<artifactId>opensaml-saml-api</artifactId>
<version>5.0.0</version>
</dependency>
<dependency>
<groupId>org.opensaml</groupId>
<artifactId>opensaml-saml-impl</artifactId>
<version>5.0.0</version>
</dependency>
4. 配置改进
4.1 XML 命名空间配置
XML 命名空间必须引用 Spring Security 7.0 模式或更新版本。早期版本不支持。
更新模式位置:
xml
<!-- 6.x 或更早版本 -->
<beans xmlns:security="http://www.springframework.org/schema/security"
xsi:schemaLocation="
http://www.springframework.org/schema/security
https://www.springframework.org/schema/security/spring-security-6.5.xsd">
<!-- 7.0 版本 - 选项 1:使用特定版本 -->
<beans xmlns:security="http://www.springframework.org/schema/security"
xsi:schemaLocation="
http://www.springframework.org/schema/security
https://www.springframework.org/schema/security/spring-security-7.0.xsd">
升级建议
1. 依赖更新
Maven 配置:
xml
<properties>
<spring-security.version>7.0.0</spring-security.version>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-bom</artifactId>
<version>${spring-security.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
Gradle 配置:
gradle
ext {
springSecurityVersion = '7.0.0'
}
dependencies {
implementation platform("org.springframework.security:spring-security-bom:${springSecurityVersion}")
implementation 'org.springframework.security:spring-security-core'
implementation 'org.springframework.security:spring-security-web'
implementation 'org.springframework.security:spring-security-config'
}
2. 迁移策略
Spring Security 7.0 支持增量迁移。建议的迁移路径:
- 准备阶段:升级到 Spring Security 6.5+,完成所有废弃 API 的替换
- 核心迁移:更新依赖和核心 API
- 功能迁移:根据具体使用情况调整 SAML、OAuth 等功能
- 测试验证:全面测试应用程序功能
3. 兼容性注意事项
- 应用程序需要确保使用 Java 17 或更高版本
- 从
javax.*命名空间迁移到jakarta.*命名空间 - 如果使用传统的访问决策 API,需要显式添加
spring-security-access依赖 - SAML 2.0 相关代码需要更新以使用 OpenSAML 5
总结
Spring Security 7.0 带来了显著的改进,包括:
- 更简洁和一致的 API 设计
- 增强的安全性功能
- 更好的性能表现
- 对现代 Java 特性的更好支持
升级到 Spring Security 7.0 需要仔细规划和测试,特别是对于使用大量自定义安全配置的应用程序。建议首先在开发环境中进行完整测试,然后逐步部署到生产环境。