如何在 Spring WebFlux 中获取当前经过身份验证的用户
我正在尝试检索身份验证对象,该对象创建用户名和权限。 我知道在 WebFlux 中我不能使用 SecurityContextHolder.getContext(),而是必须使用 ReactiveSecurityContextHolder.getContext()
但在这两种情况下,结果均为 null。
val autx = ReactiveSecurityContextHolder.getContext()
.map(SecurityContext::getAuthentication) // always null
或者
val auth = ReactiveSecurityContextHolder.getContext().filter { it.authentication != null }
.map { it.authentication.principal }.block() // always null
我理解,在从 ReactiveSecurityContextHolder 检索 auth 对象之前,必须有人将其放入其中。找不到任何示例如何执行此操作以及应在代码中的何处填充它。 理想情况下,我认为它应该在authenticate方法中的ReactiveAuthenticationManager实现中。
我将其添加到authenticate方法中:
ReactiveSecurityContextHolder.getContext()
.map { context: SecurityContext ->
context.authentication.principal
}
.cast(UserData::class.java)
.contextWrite(ReactiveSecurityContextHolder.withAuthentication(authentication))
.subscribe()
但它不会改变任何
Java或Kotlin上的工作示例值得赞赏的
配置:
@Bean
fun securityWebFilterChain(http: ServerHttpSecurity): SecurityWebFilterChain {
return http.authorizeExchange()
.pathMatchers("**/health").permitAll()
.pathMatchers("/**").authenticated()
.anyExchange().authenticated()
.and()
.authenticationManager(authenticationManager) // ReactiveAuthenticationManager impl
.securityContextRepository(securityContextRepository)
.csrf().disable()
.cors().configurationSource(corsConfig())
.and()
.build()
}
上下文存储库:
@Component
class SecurityContextRepository(
val authenticationManager: ReactiveAuthenticationManager
) : ServerSecurityContextRepository {
override fun save(swe: ServerWebExchange, sc: SecurityContext): Mono<Void> {
throw UnsupportedOperationException("SecurityContext save not supported")
// if i want to save, what should be there?
}
override fun load(serverExchange: ServerWebExchange): Mono<SecurityContext> {
val authHeader = serverExchange.request.headers.getFirst(HttpHeaders.AUTHORIZATION)
val preAuthentication = PreAuthenticatedAuthenticationToken(null, authHeader)
return this.authenticationManager.authenticate(preAuthentication)
.map { authentication -> SecurityContextImpl(authentication) }
}
}
I'm trying to retrieve authentication object, which creates user name and permissions.
I know that in WebFlux I cannot use SecurityContextHolder.getContext(), but rather must use ReactiveSecurityContextHolder.getContext()
But in both cases, result is null.
val autx = ReactiveSecurityContextHolder.getContext()
.map(SecurityContext::getAuthentication) // always null
or
val auth = ReactiveSecurityContextHolder.getContext().filter { it.authentication != null }
.map { it.authentication.principal }.block() // always null
I understand, that before retrieve auth object from ReactiveSecurityContextHolder, someone must put it into there. Cannot find any example how to do that, and where in the code it should be populated.
Ideally, I think it should be in the ReactiveAuthenticationManager implementation in the authenticate method.
I added this into authenticate method:
ReactiveSecurityContextHolder.getContext()
.map { context: SecurityContext ->
context.authentication.principal
}
.cast(UserData::class.java)
.contextWrite(ReactiveSecurityContextHolder.withAuthentication(authentication))
.subscribe()
but it doesnt change anything
working examples on Java or Kotlin are appreciated
configuration:
@Bean
fun securityWebFilterChain(http: ServerHttpSecurity): SecurityWebFilterChain {
return http.authorizeExchange()
.pathMatchers("**/health").permitAll()
.pathMatchers("/**").authenticated()
.anyExchange().authenticated()
.and()
.authenticationManager(authenticationManager) // ReactiveAuthenticationManager impl
.securityContextRepository(securityContextRepository)
.csrf().disable()
.cors().configurationSource(corsConfig())
.and()
.build()
}
context repository:
@Component
class SecurityContextRepository(
val authenticationManager: ReactiveAuthenticationManager
) : ServerSecurityContextRepository {
override fun save(swe: ServerWebExchange, sc: SecurityContext): Mono<Void> {
throw UnsupportedOperationException("SecurityContext save not supported")
// if i want to save, what should be there?
}
override fun load(serverExchange: ServerWebExchange): Mono<SecurityContext> {
val authHeader = serverExchange.request.headers.getFirst(HttpHeaders.AUTHORIZATION)
val preAuthentication = PreAuthenticatedAuthenticationToken(null, authHeader)
return this.authenticationManager.authenticate(preAuthentication)
.map { authentication -> SecurityContextImpl(authentication) }
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您需要使用
SecurityWebFilterChain
bean 定义 WebFlux 安全配置。以下是 OAuth 2.0 资源服务器的示例:您可以在此处找到更多详细信息 WebFlux 安全
You need to define WebFlux Security configuration using
SecurityWebFilterChain
bean. Here is an example for OAuth 2.0 Resource Server:You can find more details here WebFlux Security