问题描述
我有一个带有自定义过滤器的Spring Cloud Gateway。 在此过滤器中,我尝试使用参数调用我的Web客户端。来自reactivesecuritycontextholder的角色。 getAccesstoken结果a
com.xy.HeaderGatewayFilter $ apply $ 1 $ 1.apply(HeaderGatewayFilter.kt:37)。
如果我只返回了“ getAccesstoken(webClient,“ fixString”).flatMap(chain :: filter)”,而没有实际的作用,则返回一个accesstoken。
@Component
class HeaderGatewayFilter(@Autowired private val webClient: WebClient) : AbstractGatewayFilterFactory<HeaderGatewayFilter.Config>() {
open class Config
override fun apply(config: Config?): GatewayFilter {
return OrderedGatewayFilter( { exchange,chain ->
return@OrderedGatewayFilter getCurrentUserRole()
.map{rolle -> getAccesstoken(webClient,rolle )
}
.map { accesstoken ->
exchange.request
.mutate()
.header(HttpHeaders.AUTHORIZATION,"Bearer ${accesstoken}")
return@map exchange
}.flatMap(chain::filter)
},40)
fun getAccesstoken(webClient: WebClient,rolle: String): Mono<String> {
val map: MultiValueMap<String,String> = LinkedMultiValueMap()
map.add("scope","role:${rolle}")
val inserter = BodyInserters.fromFormData(map)
return webClient.post().body(inserter).retrieve().bodyToMono(Map::class.java).map {
it["access_token"] as String }
}
fun getCurrentUserRole() : Mono<String> {
return reactivesecuritycontextholder.getContext()
.switchIfEmpty(Mono.error(IllegalStateException("Context is empty")))
.map(SecurityContext::getAuthentication)
.map(Authentication::getPrincipal)
.cast(Jwt::class.java)
.map {jwt ->
return@map jwt.claims["realm_access"] as JSONObject
}
.map { realmAccess ->
return@map realmAccess["roles"] as JSONArray}
.map { rollen -> rollen.first().toString() }
}
解决方法
好的,我明白了。我级联中的所有内容都必须返回一个Mono。 我有一个映射,它返回一个String,但是现在我将其更改为Mono