18

In the GatewayFilter, I am trying to inject a header into the request like below.

@Override public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) { //DO SOME AUTHORIZATION OPERATIONS String jwt = "xxxxx" exchange.getRequest().getHeaders().add("headerkey", jwt); return chain.filter(exchange); }

But I am getting the below error:

java.lang.UnsupportedOperationException: null
at java.util.Collections$UnmodifiableMap.computeIfAbsent(Collections.java:1535) ~[na:1.8.0_111]
at org.springframework.http.HttpHeaders.add(HttpHeaders.java:1425) ~[spring-web-5.0.5.RELEASE.jar:5.0.5.RELEASE]
at com.trimble.sample.springcloudgateway.filter.AuthGatewayFilter.filter(AuthGatewayFilter.java:30) ~[classes/:na]
at org.springframework.cloud.gateway.filter.OrderedGatewayFilter.filter(OrderedGatewayFilter.java:44) ~[spring-cloud-gateway-core-2.0.0.BUILD-SNAPSHOT.jar:2.0.0.BUILD-SNAPSHOT]
at org.springframework.cloud.gateway.handler.FilteringWebHandler$DefaultGatewayFilterChain.filter(FilteringWebHandler.java:103) ~[spring-cloud-gateway-core-2.0.0.BUILD-SNAPSHOT.jar:2.0.0.BUILD-SNAPSHOT]
at org.springframework.cloud.gateway.filter.NettyWriteResponseFilter.filter(NettyWriteResponseFilter.java:62) ~[spring-cloud-gateway-core-2.0.0.BUILD-SNAPSHOT.jar:2.0.0.BUILD-SNAPSHOT]
at org.springframework.cloud.gateway.handler.FilteringWebHandler$GatewayFilterAdapter.filter(FilteringWebHandler.java:121) ~[spring-cloud-gateway-core-2.0.0.BUILD-SNAPSHOT.jar:2.0.0.BUILD-SNAPSHOT]
at org.springframework.cloud.gateway.filter.OrderedGatewayFilter.filter(OrderedGatewayFilter.java:44) ~[spring-cloud-gateway-core-2.0.0.BUILD-SNAPSHOT.jar:2.0.0.BUILD-SNAPSHOT]
at org.springframework.cloud.gateway.handler.FilteringWebHandler$DefaultGatewayFilterChain.filter(FilteringWebHandler.java:103) ~[spring-cloud-gateway-core-2.0.0.BUILD-SNAPSHOT.jar:2.0.0.BUILD-SNAPSHOT]
thaneesh shanand
  • 453
  • 1
  • 5
  • 14
  • You have to call mutate on the request and then call mutate on the exchange – spencergibb Apr 15 '18 at 18:36
  • Called the mutate methods as below: ServerHttpRequest request = exchange.getRequest() .mutate() .header("headerkey", jwt) .build(); exchange.mutate().request(request).build(); return chain.filter(exchange); However, the header is not injected to the backend api. Am I doing it wrong? – thaneesh shanand Apr 16 '18 at 01:05
  • I don't know enough information to say – spencergibb Apr 16 '18 at 01:07

3 Answers3

19

The below code works:

ServerHttpRequest request = exchange.getRequest()
                .mutate()
                .header("x-jwt-assertion", jwt)
                .build();
ServerWebExchange exchange1 = exchange.mutate().request(request).build();
            return chain.filter(exchange1);
thaneesh shanand
  • 453
  • 1
  • 5
  • 14
14

You can take a look at

org.springframework.cloud.gateway.filter.factory.*GatewayFilterFactory

There are many useful gateway filter implementations.

For your question,

org.springframework.cloud.gateway.filter.factory.AddRequestHeaderGatewayFilterFactory

has a standard implementation.

public class AddRequestHeaderGatewayFilterFactory extends AbstractNameValueGatewayFilterFactory {

    @Override
    public GatewayFilter apply(NameValueConfig config) {
        return (exchange, chain) -> {
            ServerHttpRequest request = exchange.getRequest().mutate()
                    .header(config.getName(), config.getValue())
                    .build();

            return chain.filter(exchange.mutate().request(request).build());
        };
    }
}
leeroycool
  • 23
  • 2
steven.tong
  • 345
  • 3
  • 16
0
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
    exchange.getRequest()
            .mutate()
            .headers(httpHeaders -> httpHeaders.setBearerAuth("token"));
    return chain.filter(exchange);
}
fire_Rising
  • 70
  • 1
  • 7