403 迁移到 Spring Boot 3 后禁止使用基本身份验证的挂起控制器方法

问题描述 投票:0回答:3

我最近将 Spring Boot MVC Kotlin 项目迁移到 Spring Boot 3。基本身份验证用于 REST 控制器(通过

SecurityFilterChain
配置 - 也从基于
WebSecurityConfigurerAdapter
的安全性迁移)。从那时起,对由 suspend 控制器方法处理的端点的所有调用都会返回 403。对于其他端点,它工作正常。

迁移前所有端点都工作正常。当我们使控制器方法不挂起时(使用

runBlocking
),它可以正常工作。

有趣的是,控制器方法的主体被执行。我注意到,请求多次通过安全过滤器链,并且在默认情况下被标记为未经授权。那里的请求参数不包含所需的身份验证标头,即使在第一次通过时也包含在内。

一些默认的

AnonymousAuthenticationFilter

逻辑被禁用:

HttpSecurity

看来涉及到协程的时候,授权逻辑会被触发两次。一旦工作正常。由于缺少身份验证标头,第二次失败。

我尝试启用禁用的默认设置,但这没有帮助。

spring-boot kotlin spring-mvc spring-security kotlin-coroutines
3个回答
1
投票

在新的 Spring 版本中,不仅初始请求处理(调度程序类型“REQUEST”)经过安全链,而且在像我使用 Kotlin 挂起处理程序方法那样进行异步调用的情况下,甚至异步处理也会在新的线程必须经过它(调度程序类型“ASYNC”)。这意味着授权完成了两次。 2.
    http .csrf().disable() .headers().disable() .sessionManagement().disable() .securityContext().disable() .requestCache().disable() .servletApi().disable() .apply(DefaultLoginPageConfigurer()).disable() .logout().disable()
  1. 是仅在第一轮过滤中运行的
    BasicAuthenticationFilter
    - 这次安全上下文未更新。
    由于我们在请求之间禁用了安全上下文存储
  2. OncePerRequestFilter
  3. ,因此在第二轮过滤中丢失了安全上下文,因此该请求被视为未经授权。
    
    
  4. 对此有几种可能的解决方案。禁用“ASYNC”调度程序类型的请求的安全链处理,启用记住请求之间的安全上下文,或其他一些。


0
投票

当您尝试向按线程(而不是协程)处理安全操作的应用程序添加异步请求时,会发生错误。

要在控制器中使用

suspend fun

,您必须使用自定义的 CoroutineSecurityContext (如 this 之一)。 一些注意事项

重要的是要了解,在应用程序中使用异步和同步方法是不好的做法,因为它可能导致线程阻塞并降低性能,因为同步请求可能会阻塞线程。

我在上传到 AWS S3 并使用 Kotlin SDK 时遇到了同样的问题。我用 runBlocking/launch 解决了这个问题,这对我来说已经足够了。将来,我可能会根据性能需求切换到反应式堆栈。


0
投票

http.securityContext().disable()

© www.soinside.com 2019 - 2024. All rights reserved.