Header based bearer authentication with feign-reactive

397 Views Asked by At

We are currently working on a service-based architecture, in which each service follows a reactive approach and uses Spring WebFlux and Spring Boot. Furthermore, each service is secured via an OAuth2 bearer token approach that is send via headers.

The communication between the frontend (or a REST client) to the backend services works already quite fine and we are currently adding some communication between the backend services. For this we would like to use Feign and since we have a reactive approach, we would like to use feign-reactive (https://github.com/PlaytikaOSS/feign-reactive). However, we have now the following problem:

It seems that feign-reactive adds the Authorization header as an Array (at least according to the log output (Note: I removed the JWT Token)):

2023-04-27 17:27:25.297 TRACE 27701 --- [ctor-http-nio-3] c.n.p.i.c.client.UserSettingsClient      : [UserSettingsClient#getDatasource(UUID,String)] REQUEST HEADERS
Authorization:[Bearer <JWT token>]

As a consequence the receiving service returns a "401 Unauthorized" exception, since it does not recognises the bearer token as an Array. As I wrote above, when we connect to the services without the Array, i.e., via the header Authorization: Bearer <JWT token>, everything works fine.

We already tried to use the @RequestHeader annotation,

@GetMapping("/api/v1/datasource/{id}")
Mono<DatasourceDTO> getDatasource(@PathVariable UUID id, @RequestHeader(value = "Authorization", required = true) String jwtToken);

as well as, an interceptor

    @Bean
    public ReactiveHttpRequestInterceptor reactiveHttpRequestInterceptor() {
        return reactiveHttpRequest -> {

            Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
            if (authentication != null && authentication.getPrincipal() instanceof Jwt) {
                Jwt jwt = (Jwt) authentication.getPrincipal();
                reactiveHttpRequest.headers().put("Authorization", Collections.singletonList("Bearer " + jwt.getTokenValue()));
                return Mono.just(reactiveHttpRequest);
            } 
        }
        ;
    }

with the same result. In the interceptor we used the Collections.singletonList method (which creates a List), because the headers variable is of the type Map<String, List<String>>, thus we have to pass a list. We tested it with feign-reactive version 3.3.0 and 4.0.0

Is there a way to tell feign-reactive to not use an Array for the headers, but only the string? Or can we tell the receiving service somehow to also accept an Array (of size 1)?

Thank you in advance.

0

There are 0 best solutions below