此版本仍在开发中,尚未被视为稳定版本。对于最新的稳定版本,请使用 Spring Security 6.4.5! |
Spring Security 6.3 中的新增功能
Spring Security 6.3 提供了许多新功能。 以下是该版本的亮点,或者您可以查看发行说明,了解每项功能和错误修复的详细列表。
被动 JDK 序列化支持
在支持 JDK 序列化安全组件方面, Spring Security 历来非常激进,仅支持一个 Spring Security 次要版本的每个序列化版本。 这意味着,如果您有 JDK 序列化的安全组件,则需要在升级到下一个 Spring Security 版本之前撤离它们,因为它们将不再可反序列化。
现在 Spring Security 每 6 个月执行一次次要版本,这成为一个更大的痛点。 为了解决这个问题,Spring Security 现在将保持对 JDK 序列化的被动性,就像对 JSON 序列化所做的那样,从而实现更无缝的升级。
授权
最近几个版本的一个持续主题是重构和改进 Spring Security 的授权子系统。
首先将AccessDecisionManager
API 替换为AuthorizationManager
现在已经到了我们能够添加几个令人兴奋的新功能的地步。
批注参数 - #14480
6.3 的第一个功能是支持 Comments 参数。 考虑一下 Spring Security 对元注释的支持,如下所示:
-
Java
-
Kotlin
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
@PreAuthorize("hasAuthority('SCOPE_message:read')")
public @interface HasMessageRead {}
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
@PreAuthorize("hasAuthority('SCOPE_message:read')")
annotation class HasMessageRead
在此版本之前,仅当它在整个代码库中广泛使用时,此类内容才有用。 但现在,您可以添加如下参数:
-
Java
-
Kotlin
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
@PreAuthorize("hasAuthority('SCOPE_{scope}')")
public @interface HasScope {
String scope();
}
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
@PreAuthorize("hasAuthority('SCOPE_{scope}')")
annotation class HasScope (val scope:String)
使执行此类作成为可能:
-
Java
-
Kotlin
@HasScope("message:read")
public String method() { ... }
@HasScope("message:read")
fun method(): String { ... }
并在更多位置应用 SpEL 表达式。
安全返回值 - #14596、#14597
从 Spring Security 的早期开始,您就能够注释 Spring bean@PreAuthorize
和@PostAuthorize
.
但是,控制器、服务和存储库并不是您唯一需要保护的东西。
例如,域对象呢Order
其中只有管理员才能调用Order#getPayment
方法?
现在在 6.3 中,您也可以对这些方法进行注释。
首先,注释getPayment
方法:
-
Java
-
Kotlin
public class Order {
@HasScope("payment:read")
Payment getPayment() { ... }
}
class Order {
@HasScope("payment:read")
fun getPayment(): Payment { ... }
}
-
Java
-
Kotlin
public interface OrderRepository implements CrudRepository<Order, String> {
@AuthorizeReturnObject
Optional<Order> findOrderById(String id);
}
interface OrderRepository : CrudRepository<Order, String> {
@AuthorizeReturnObject
fun findOrderById(id: String?): Optional<Order?>?
}
此时,Spring Security 将保护任何Order
返回自findOrderById
通过代理Order
实例.
错误处理 - #14598、#14600、#14601
在此版本中,您还可以使用其最后一个新方法安全注释在方法级别拦截和处理失败。
-
Java
-
Kotlin
public class Payment {
@HandleAuthorizationDenied(handlerClass=Mask.class)
@PreAuthorize("hasAuthority('card:read')")
public String getCreditCardNumber() { ... }
}
class Payment {
@HandleAuthorizationDenied(handlerClass=Mask.class)
@PreAuthorize("hasAuthority('card:read')")
fun getCreditCardNumber(): String { ... }
}
并发布一个Mask
豆:
-
Java
-
Kotlin
@Component
public class Mask implements MethodAuthorizationDeniedHandler {
@Override
public Object handleDeniedInvocation(MethodInvocation invocation, AuthorizationResult result) {
return "***";
}
}
@Component
class Mask : MethodAuthorizationDeniedHandler {
fun handleDeniedInvocation(invocation: MethodInvocation?, result: AuthorizationResult?): Any = "***"
}
然后对Payment#getCreditCardNumber
将返回而不是数字。***
您可以在最新的 Spring Security Data 示例中看到所有这些功能协同工作。
密码检查泄露 - #7395
如果您要让用户选择密码,那么确保此类密码尚未泄露至关重要。
Spring Security 6.3 使这变得如此简单,就像发布CompromisedPasswordChecker
豆:
-
Java
-
Kotlin
@Bean
public CompromisedPasswordChecker compromisedPasswordChecker() {
return new HaveIBeenPwnedRestApiPasswordChecker();
}
@Bean
fun compromisedPasswordChecker(): CompromisedPasswordChecker = HaveIBeenPwnedRestApiPasswordChecker()
spring-security-rsa
现在是 Spring Security 的一部分 - #14202
自 2017 年以来,Spring Security 一直在进行一项长期计划,将各种 Spring Security 扩展折叠到 Spring Security 中。
在 6.3 中,spring-security-rsa
成为这些项目中的最新项目,这将帮助团队长期维护和添加功能。
spring-security-rsa
提供了多个方便BytesEncryptor
implementations 以及一个更简单的 APIKeyStore
s.
OAuth 2.0 令牌交换授权 - #5199
Spring Security 中票数最高的 OAuth 2.0 功能之一现已在 6.3 中推出,即对 OAuth 2.0 Token Exchange 授权的支持。
对于任何配置为令牌交换的客户端,您可以在 Spring Security 中通过添加TokenExchangeAuthorizedClientProvider
实例复制到OAuth2AuthorizedClientManager
这样:
-
Java
-
Kotlin
@Bean
public OAuth2AuthorizedClientProvider tokenExchange() {
return new TokenExchangeOAuth2AuthorizedClientProvider();
}
@Bean
fun tokenExchange(): OAuth2AuthorizedClientProvider = TokenExchangeOAuth2AuthorizedClientProvider()
然后使用@RegisteredOAuth2AuthorizedClient
注解像往常一样,以资源服务器所需的扩展权限检索适当的令牌。
其他亮点
-
gh-14655 - 添加
DelegatingAuthenticationConverter
-
gh-14193 - 添加了对 CAS 网关身份验证的支持
-
gh-13259 - 自定义调用 UserInfo 的时间
-
gh-14168 - 在 OAuth2AuthorizationRequestRedirectFilter 中引入可自定义的 AuthorizationFailureHandler
-
gh-14672 - 从 OidcUserRequest 和 OidcUserInfo 自定义 OidcUser 的映射
-
gh-13763 - 简化反应式 OAuth2 客户端组件模型的配置
-
gh-10538 - 支持证书绑定的 JWT 访问令牌验证
-
gh-14265 - 在 UserInfo 响应中支持嵌套用户名
-
gh-14449 - 添加
SecurityContext
参数解析器 -
gh-11440 - 简化禁用
application/x-www-form-urlencoded
对客户端 ID 和 Secret 进行编码(servlet 文档、反应式文档)