如何将我的ReactiveSecurityContextHolder角色传递给mono webclient剩余调用?

问题描述

我有一个带有自定义过滤器的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