spring-cloud-gateway
spring-cloud-gateway copied to clipboard
Redirection fails since custom response status 302 code overwritten with 200 status code
Spring cloud Gateway version: 4.1.0 I am trying to develop a global pre-filter that intercepts the incoming login request and use redirection to redirect to landing page if user is already logged-in. For this I have developed a custom pre-filter that updates the response status code to custom status 302 (HttpStatus.FOUND) and location header with the landing page url as follows:
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
// check if request is for login and user session is valid
ServerHttpResponse response = exchange.getResponse();
boolean updateStatus = response.setStatusCode(HttpStatus.FOUND);
log.debug("Response status code update: {}", updateStatus);
log.debug("Updated response status code: {}", response.getStatusCode());
response.getHeaders().add(HttpHeaders.LOCATION, "<landingPageUrl> here");
return response.setComplete();
}
After the successful boot up of the Spring Cloud Gateway application, I logged-in in the website and then tried to access the login page again. But the browser is not performing redirection because the response status code returned to browser is 200 instead of 302. It seems the custom status code is getting overwritten somehow. Note: The Location header is updated correctly and returned to the browser.
I tried to troubleshoot the issue and checked the logs and found following log files written by above code:
Response status code update: true
Updated response status code: 302 FOUND
I am now clueless about at which point the response status is getting overwritten in the request flow.
I also read about in-built RedirectTo gateway filter provided by Spring Cloud Gateway, however I need to update status code through code only. https://docs.spring.io/spring-cloud-gateway/reference/spring-cloud-gateway/gatewayfilter-factories/redirectto-factory.html
Even I browsed the code of RedirectTo Gateway filter and found it has also been implemented in similar code. https://github.com/spring-cloud/spring-cloud-gateway/blob/main/spring-cloud-gateway-server/src/main/java/org/springframework/cloud/gateway/filter/factory/RedirectToGatewayFilterFactory.java
PS: I have already gone through articles and none of them are working for me: Spring Cloud Gateway: Set response status code in custom predicate Spring Cloud Gateway Change Response
Please help in setting custom status 302 in response through code and return to browser to perform redirection.
@kimmking Thanks for checking. I have implemented above code in one of the pre filter which is a global filter. This pre filter executes as part of multiple global pre filters in chain. I can observe that response.setComplere() does not make request to downstream endpoint (working as expected), however in browser the status is recieved as 200 instead of 302 due to which redirection does not happen. Have you also tested code in global filter chain?
you can also use RedirectTo GatewayFilter edirectTo GatewayFilter Factory
@kimmking Thanks for your suggestion. I have already checked RedirectTo gateway filter. However, the scenario that I am trying to implement can be implemented programmatically only and not through configuration. Since when login request (request uri: /login/) is received without valid session, then login page must be displayed for authentication. And when same login request(request uri: /login/) is received with valid session, then landing page must be displayed using redirection. Is there any possible Spring Cloud Gateway configuration that I can check for the reported issue? or any troubleshooting tips?
If you'd like us to spend some time investigating, please take the time to provide a complete, minimal, verifiable sample (something that we can unzip attached to this issue or git clone, build, and deploy) that reproduces the problem.
@spencergibb this issue is resolved. The updated redirection status was not propagated in filter chain due to which 200 status was getting returned. However, after redirection the subsequent global pre and post filters are skipped. Anyways that does not have major impact in the functionality.