如何通过REACTIVE虚拟客户端使用受基本身份验证保护的Restful Web服务

时间:2020-03-09 22:55:02

标签: spring-boot security spring-webflux spring-cloud-feign

@ReactiveFeignClient(name = "service.b",configuration = CustomConfiguration.class)
public interface FeingConfiguration {

    @PostMapping("/api/students/special")
    public Flux<Student> getAllStudents(@RequestBody Flux<SubjectStudent> lista);

}

帮助,如何向服务(service.b)中的标头添加基本身份验证。 我有CustomConfiguration.class类,但是不允许我,我有401个授权失败

@Configuration
public class CustomConfiguration {

    @Bean
    public BasicAuthRequestInterceptor basic() {
        return  new BasicAuthRequestInterceptor("user","user") ;
    }

2 个答案:

答案 0 :(得分:1)

好像您正在尝试使用伪装反应(https://github.com/Playtika/feign-reactive)来实现REST客户端。我也在我的一个项目中使用它,看来该库没有指定常规身份验证凭据的即用型方法。至少没有办法声明性地这样做。因此,除了通过@ReactiveFeignClient放弃自动配置并开始手动配置反应式假客户端之外,我没有找到比这更好的方法了。这样,您可以向所有传出请求中手动添加“授权”标头。因此,提供此客户端定义:

public interface FeingClient {

    @PostMapping("/api/students/special")
    public Flux<Student> getAllStudents(@RequestBody Flux<SubjectStudent> lista);

}

将以下配置类添加到您的Spring上下文中,用您自己的数据替换用户名,密码和service-url:

@Configuration
public class FeignClientConfiguration {
    
    @Bean
    FeignClient feignClient() {
        WebReactiveFeign
            .<FeignClient>builder()
            .addRequestInterceptor(request -> {
                request.headers().put(
                    "Authorization", 
                     Collections.singletonList(
                        "Basic " + Base64.getEncoder().encodeToString( 
                            "username:password".getBytes(StandardCharsets.ISO_8859_1))));
                return request;
            })
            .target(FeignClient.class, "service-url");
    }
}

请注意,用于响应式伪装客户端的手动配置的此API在不同版本的响应式伪装库之间可能有所不同。还要注意,这种方法有一个主要缺点-如果您开始手动为feign客户创建Bean,则将失去Feign的主要优势-能够用几行代码声明性地编写REST-client。例如。如果您想将上述客户端与某种客户端负载平衡机制一起使用,例如Ribbon / Eureka或Ribbon / Kubernetes,则还需要手动进行配置。

答案 1 :(得分:0)

您可以使用直接拦截器:

@Configuration
class FeignClientConfiguration {
    @Bean
    fun reactiveHttpRequestInterceptor(): ReactiveHttpRequestInterceptor {
        return ReactiveHttpRequestInterceptor { request: ReactiveHttpRequest ->
            request.headers()["Authorization"] = //insert data from SecurityContextHolder;
            Mono.just(request)
        }
    }
}