Webflux, как перехватить запрос и добавить новый заголовок - PullRequest
0 голосов
/ 15 октября 2019

Используя фильтр Webflux, я пытаюсь перехватить запросы и проверить, поступает ли запрос от определенного URI, затем добавить новый Authorization заголовок

Код фильтра прост и понятен

@Component
@Order(Ordered.HIGHEST_PRECEDENCE)
public class AuthorizationFilter implements WebFilter {

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) {

        return chain.filter(Optional.of(exchange)
                .filter(serverWebExchange -> serverWebExchange.getRequest().getURI().getPath().endsWith("/callback"))
                .map(serverWebExchange -> addNewHeader(serverWebExchange))
                .orElse(exchange));
    }

    private ServerWebExchange addNewHeader(ServerWebExchange serverWebExchange) {

        String authHeader=serverWebExchange.getRequest().getQueryParams().get("state").get(0);

        if (authHeader == null) {
            throw new BadRequestException("State not complete (access_token missing) for //callback");
        }

        try {
            serverWebExchange.getRequest().getHeaders().setBearerAuth(authHeader);
        }catch (Throwable t){
            t.printStackTrace();
        }

        return serverWebExchange;
    }
}

Но возникает исключение

java.lang.UnsupportedOperationException
    at org.springframework.http.ReadOnlyHttpHeaders.set(ReadOnlyHttpHeaders.java:99)
    at org.springframework.http.HttpHeaders.setBearerAuth(HttpHeaders.java:774)

Кажется, карта заголовка доступна только для чтения. Как я могу решить эту проблему и добавить новый заголовок?

Ответы [ 2 ]

1 голос
/ 16 октября 2019

Проблемы, вызванные тем, что вы добавляете новый заголовок в оператор map цепочки, в этом случае webflux завершается serverWebExchange, и он является неизменным. Вам просто нужно добавить заголовок перед вызовом chain.filter(...).

1 голос
/ 15 октября 2019

Вы можете изменить ServerWebExchange и его ServerHttpRequest с помощью их mutate() методов, которые возвращают 'Builder' для каждого из них.

Пример Java:

@Component
public class AuthorizationFilter implements WebFilter {
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) {
        ServerHttpRequest mutatedRequest = exchange.getRequest().mutate().header(HttpHeaders.AUTHORIZATION, "Bearer " + authHeader).build();
        ServerWebExchange mutatedExchange = exchange.mutate().request(mutatedRequest).build();
        return chain.filter(mutatedExchange);
    }
}

Пример Kotlin:

@Component
class AuthorizationFilter : WebFilter {
    override fun filter(exchange: ServerWebExchange, chain: WebFilterChain): Mono<Void> {
        val mutatedRequest = exchange.request.mutate().header(HttpHeaders.AUTHORIZATION, "Bearer $authHeader").build()
        val mutatedExchange = exchange.mutate().request(mutatedRequest).build()
        return chain.filter(mutatedExchange)
    }
}
...