此版本仍在开发中,尚未被视为稳定版本。对于最新的稳定版本,请使用 Spring Security 6.3.3! |
此版本仍在开发中,尚未被视为稳定版本。对于最新的稳定版本,请使用 Spring Security 6.3.3! |
Spring Security 6.3 提供了许多新功能。 以下是该版本的亮点,或者您可以查看发行说明,了解每项功能和错误修复的详细列表。
被动 JDK 序列化支持
在支持 JDK 序列化安全组件方面, Spring Security 历来非常激进,仅支持一个 Spring Security 次要版本的每个序列化版本。 这意味着,如果您有 JDK 序列化的安全组件,则需要在升级到下一个 Spring Security 版本之前撤离它们,因为它们将不再可反序列化。
现在 Spring Security 每 6 个月执行一次次要版本,这成为一个更大的痛点。 为了解决这个问题,Spring Security 现在将保持对 JDK 序列化的被动性,就像对 JSON 序列化所做的那样,从而实现更无缝的升级。
授权
最近几个版本的一个持续主题是重构和改进 Spring Security 的授权子系统。
从替换 API 开始,现在已经到了我们能够添加几个令人兴奋的新功能的地步。AccessDecisionManager
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 的早期开始,你就能够用 @PreAuthorize
和 @PostAuthorize
注释 Spring bean。
但是,控制器、服务和存储库并不是您唯一需要保护的东西。
例如,只有管理员才能调用该方法的域对象呢?Order
Order#getPayment
现在在 6.3 中,您也可以对这些方法进行注释。
首先,像 Spring bean 一样对方法进行 Comments:getPayment
-
Java
-
Kotlin
public class Order {
@HasScope("payment:read")
Payment getPayment() { ... }
}
class Order {
@HasScope("payment:read")
fun getPayment(): Payment { ... }
}
然后使用 @AuthorizeReturnObject
注释您的 Spring Data 存储库,如下所示:
-
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
实例来保护从中返回的任何内容。Order
findOrderById
错误处理 - #14598、#14600、#14601
在此版本中,您还可以使用其最后一个新方法安全注释在方法级别拦截和处理失败。
当您使用 @HandleAuthorizationDenied 注释方法时,
如下所示:
-
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 { ... }
}
并发布一个 bean: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
bean 一样简单:
-
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
实现以及用于使用 KeyStore
的更简单的 API。
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
注释来检索具有 Resource Server 所需的扩展权限的相应令牌。
其他亮点
-
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 - 简化禁用编码客户端 ID 和密钥(servlet 文档、反应式文档
application/x-www-form-urlencoded
)