Using Webflux
filter, I am trying to intercept the requests and check if the request is coming from certain URI
then add a new Authorization
header
The filter code is simple and straightforward
@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;
}
}
But it throws an exception
java.lang.UnsupportedOperationException
at org.springframework.http.ReadOnlyHttpHeaders.set(ReadOnlyHttpHeaders.java:99)
at org.springframework.http.HttpHeaders.setBearerAuth(HttpHeaders.java:774)
It seems the header map is read only.How can i overcome this issue and add the new Header ?
You can mutate the ServerWebExchange
and its ServerHttpRequest
with their mutate()
methods which returns a 'Builder' for each of them.
Example 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);
}
}
Example 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)
}
}
The problems caused because you add a new header in the map
operator of the chain, in this case webflux finilized serverWebExchange
and it is immutable. You just need to add a header before calling chain.filter(...)
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With