spring - JWT 令牌反应式身份验证出错
问题描述
我正在学习反应式编程和 spring-webflux,并且我正在尝试实现 JWT 令牌授权,但我收到有关 ResponseEntity 的运行时错误:
open class JwtReactiveAuthenticationManager(
private val userDetailsService: ReactiveUserDetailsService,
private val passwordEncoder: PasswordEncoder
): ReactiveAuthenticationManager {
private val log: Logger = LoggerFactory.getLogger(this.javaClass)
override fun authenticate(authentication: Authentication): Mono<Authentication> {
return if (authentication.isAuthenticated) {
Mono.just(authentication)
} else Mono.just(authentication)
.switchIfEmpty(Mono.error(BadCredentialsException("Invalid Credentials")))
.cast(UsernamePasswordAuthenticationToken::class.java)
.flatMap { authenticationToken: UsernamePasswordAuthenticationToken -> authenticateToken(authenticationToken) }
.publishOn(Schedulers.parallel())
.onErrorResume { Mono.error(BadCredentialsException("Invalid Credentials")) }
.filter { u: UserDetails -> passwordEncoder.matches(authentication.credentials as String, u.password) }
.switchIfEmpty(Mono.error(BadCredentialsException("Invalid Credentials")))
.map { u: UserDetails -> UsernamePasswordAuthenticationToken(authentication.principal, authentication.credentials, u.authorities) }
}
private fun authenticateToken(authenticationToken: UsernamePasswordAuthenticationToken): Mono<UserDetails>? {
val username = authenticationToken.name
log.info("checking authentication for user $username")
if (username != null && SecurityContextHolder.getContext().authentication == null) {
log.info("authenticated user $username, setting security context")
return this.userDetailsService.findByUsername(username)
}
return null
}
}
调用的控制器方法:
@GetMapping("")
override fun list(): Flux<ResponseEntity<Exercise>> {
return repo.findAll().map { o -> ResponseEntity(o, HttpStatus.OK) }
}
2020-01-09 17:54:15.790 ERROR 14680 --- [oundedElastic-1] a.w.r.e.AbstractErrorWebExceptionHandler : [e22e00ce] 500 Server Error for HTTP GET "/api/exercises"
java.lang.IllegalArgumentException: Only a single ResponseEntity supported
at org.springframework.util.Assert.isTrue(Assert.java:118) ~[spring-core-5.2.2.RELEASE.jar:5.2.2.RELEASE]
Suppressed: reactor.core.publisher.FluxOnAssembly$OnAssemblyException:
Error has been observed at the following site(s):
|_ checkpoint ? org.springframework.security.web.server.authentication.AuthenticationWebFilter [DefaultWebFilterChain]
|_ checkpoint ? org.springframework.security.web.server.authorization.AuthorizationWebFilter [DefaultWebFilterChain]
|_ checkpoint ? org.springframework.security.web.server.authentication.AuthenticationWebFilter [DefaultWebFilterChain]
|_ checkpoint ? org.springframework.security.web.server.authorization.ExceptionTranslationWebFilter [DefaultWebFilterChain]
|_ checkpoint ? org.springframework.security.web.server.savedrequest.ServerRequestCacheWebFilter [DefaultWebFilterChain]
|_ checkpoint ? org.springframework.security.web.server.context.SecurityContextServerWebExchangeWebFilter [DefaultWebFilterChain]
|_ checkpoint ? org.springframework.security.web.server.context.ReactorContextWebFilter [DefaultWebFilterChain]
|_ checkpoint ? org.springframework.security.web.server.header.HttpHeaderWriterWebFilter [DefaultWebFilterChain]
|_ checkpoint ? org.springframework.security.config.web.server.ServerHttpSecurity$ServerWebExchangeReactorContextWebFilter [DefaultWebFilterChain]
|_ checkpoint ? org.springframework.security.web.server.WebFilterChainProxy [DefaultWebFilterChain]
|_ checkpoint ? org.springframework.boot.actuate.metrics.web.reactive.server.MetricsWebFilter [DefaultWebFilterChain]
|_ checkpoint ? HTTP GET "/api/exercises" [ExceptionHandlingWebHandler]
Stack trace:
at org.springframework.util.Assert.isTrue(Assert.java:118) ~[spring-core-5.2.2.RELEASE.jar:5.2.2.RELEASE]
at org.springframework.web.reactive.result.method.annotation.ResponseEntityResultHandler.handleResult(ResponseEntityResultHandler.java:121) ~[spring-webflux-5.2.2.RELEASE.jar:5.2.2.RELEASE]
at org.springframework.web.reactive.DispatcherHandler.handleResult(DispatcherHandler.java:169) ~[spring-webflux-5.2.2.RELEASE.jar:5.2.2.RELEASE]
at org.springframework.web.reactive.DispatcherHandler.lambda$handle$2(DispatcherHandler.java:147) ~[spring-webflux-5.2.2.RELEASE.jar:5.2.2.RELEASE]
at org.springframework.web.reactive.DispatcherHandler$$Lambda$1353.000000001B373A70.apply(Unknown Source) ~[na:na]
at reactor.core.publisher.MonoFlatMap$FlatMapMain.onNext(MonoFlatMap.java:118) ~[reactor-core-3.3.1.RELEASE.jar:3.3.1.RELEASE]
at reactor.core.publisher.Operators$MonoSubscriber.complete(Operators.java:1630) ~[reactor-core-3.3.1.RELEASE.jar:3.3.1.RELEASE]
at reactor.core.publisher.MonoFlatMap$FlatMapInner.onNext(MonoFlatMap.java:241) ~[reactor-core-3.3.1.RELEASE.jar:3.3.1.RELEASE]
解决方案
您不能Flux<ResponseEntity<Exercise>>
像在多个响应实体中那样返回。
将其更改为:
@GetMapping("")
override fun list(): Flux<Exercise> {
return repo.findAll()
}
如果您希望将数据流式传输到调用客户端,它可能会好很多。
推荐阅读
- sql-server - 用于删除当前和未来日期的 SQL 查询?
- unity3d - 如何旋转对象以沿矢量 Unity3D 指向
- python - 将数据添加到 CSV 文件的新列和第一行
- angular - 错误 TS2304:部署云功能 firebase 时找不到名称“元素”
- selenium - NightwatchJS - 手动运行 Selenium 服务器时无法创建会话
- vba - VBA,带工作表,清除表格内容
- spring-boot - Spring Boot @Pattern 自定义消息不起作用
- javascript - Chartist 关于没有 jQuery 的点击功能
- ios - 重用“昂贵”的 UIViewController
- angular - Angular - 由 *ngFor 创建的输入会导致在触发模糊事件时显示重复值