我有带有自定义过滤器的 Spring Cloud Gateway。在这个过滤器中,我尝试使用参数调用我的 webclient。来自 ReactiveSecurityContextHolder 的角色。getAccessToken 结果是
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() }
}