Spring Security 6.3 中的新增功能
Spring Security 6.3 提供了许多新功能。以下是该版本的主要内容,或者你可以查看 发行说明 以详细了解每个功能和错误修复。
被动 JDK 序列化支持
在对 JDK 序列化安全组件的支持方面,Spring Security 历来非常激进,只为一个 Spring Security 小版本支持每个序列化版本。这意味着如果你有 JDK 序列化的安全组件,那么在升级到下一个 Spring Security 版本之前,需要先撤离它们,因为它们将不再可反序列化。
现在 Spring Security 每六个月执行一次小版本发布,这变成了一个更大的痛点。为了解决这个问题,Spring Security 现在将 保持 JDK 序列化的被动性,就像它对 JSON 序列化所做的那样,从而实现更无缝的升级。
授权
过去几个版本的持续主题是重构和改进 Spring Security 的授权子系统。从用 AuthorizationManager
替换 AccessDecisionManager
API 开始,现在我们已经能够添加几个令人兴奋的新功能。
注释参数 - #14480
-
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 一样注释 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
bean
-
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 令牌交换授权的支持。
对于为令牌交换配置的任何客户端,您可以通过向 OAuth2AuthorizedClientManager
添加 TokenExchangeAuthorizedClientProvider
实例来在 Spring Security 中激活它,如下所示
-
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 和密钥(Servlet 文档,响应式文档)