首页 > 解决方案 > 从响应式 Spring 服务调用阻塞 feign 客户端

问题描述

我试图从反应弹簧通量中调用生成的假装客户端,如下所示:

            .doOnNext(user1 -> {
            ResponseEntity<Void> response = recorderClient.createUserProfile(new UserProfileDto().principal(user1.getLogin()));
            if (!response.getStatusCode().equals(HttpStatus.OK)) {
                log.error("recorder backend could not create user profile for user: {} ", user1.getLogin());
                throw new RuntimeException("recorder backend could not create user profile for login name" + user1.getLogin());
            }
        })

调用已执行,但是当我尝试从反应式安全上下文(在 requets 拦截器中)检索 jwt 令牌时,如下所示:

    public static Mono<String> getCurrentUserJWT() {
    return ReactiveSecurityContextHolder
        .getContext()
        .map(SecurityContext::getAuthentication)
        .filter(authentication -> authentication.getCredentials() instanceof String)
        .map(authentication -> (String) authentication.getCredentials());
}

……

SecurityUtils.getCurrentUserJWT().blockOptional().ifPresent(s -> template.header(AUTHORIZATION_HEADER, String.format("%s %s", BEARER, s)));

上下文为空。由于我对反应弹簧还很陌生,所以我肯定会搞砸一些愚蠢而重要的事情。

标签: springjwtwebfluxreactivesecuritycontextholder

解决方案


不知道你的拦截器是如何配置的,但就我而言,我只是简单地实现ReactiveHttpRequestInterceptor并覆盖 apply() 函数

import feign.RequestInterceptor;
import feign.RequestTemplate;
import org.springframework.stereotype.Component;
import reactivefeign.client.ReactiveHttpRequest;
import reactivefeign.client.ReactiveHttpRequestInterceptor;
import reactor.core.publisher.Mono;

import java.util.Collections;

@Component
public class UserFeignClientInterceptor implements ReactiveHttpRequestInterceptor {

    private static final String AUTHORIZATION_HEADER = "Authorization";
    private static final String BEARER = "Bearer";

    @Override
    public Mono<ReactiveHttpRequest> apply(ReactiveHttpRequest reactiveHttpRequest) {
        return SecurityUtils.getCurrentUserJWT()
            .flatMap(s -> {
                reactiveHttpRequest.headers().put(AUTHORIZATION_HEADER, Collections.singletonList(String.format("%s %s", BEARER, s)));
                return Mono.just(reactiveHttpRequest);
            });
    }
}

推荐阅读