7

How can i configure http->https redirect in spring webflux? I need all http request be redirected to https(as i understood any http request should have 301 http status response with change http->https). Didn't found any information about it in documentation. I found this answer, but it related to tomcat. I have netty.

Zufar Muhamadeev
  • 3,085
  • 5
  • 23
  • 51
  • in that answer there are different answers. did you try https://stackoverflow.com/a/38829838/6565093 – pvpkiran Mar 01 '18 at 09:03
  • Thanks for comment @pvpkiran, I use default port 8080, and i also don't have configured security(not need secuity at this project). No `WebSecurityConfigurerAdapter` at classpath. – Zufar Muhamadeev Mar 01 '18 at 09:38

3 Answers3

13

I found way, hope it helps somebody:

@Bean
public WebFilter httpsRedirectFilter() {
    return new WebFilter() {
        @Override
        public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) {
            URI originalUri = exchange.getRequest().getURI();

            //here set your condition to http->https redirect
            List<String> forwardedValues = exchange.getRequest().getHeaders().get("x-forwarded-proto");
            if (forwardedValues != null && forwardedValues.contains("http")) {
                try {
                    URI mutatedUri = new URI("https",
                            originalUri.getUserInfo(),
                            originalUri.getHost(),
                            originalUri.getPort(),
                            originalUri.getPath(),
                            originalUri.getQuery(),
                            originalUri.getFragment());
                    ServerHttpResponse response = exchange.getResponse();
                    response.setStatusCode(HttpStatus.MOVED_PERMANENTLY);
                    response.getHeaders().setLocation(mutatedUri);
                    return Mono.empty();
                } catch (URISyntaxException e) {
                    throw new IllegalStateException(e.getMessage(), e);
                }
            }
            return chain.filter(exchange);
        }
    };
}
Zufar Muhamadeev
  • 3,085
  • 5
  • 23
  • 51
  • But how to specify the http port? As in yml file the https port is mentioned. `server.port: 8443` – Arpan Das Jul 03 '18 at 11:15
  • @ArpanDas this is for situation when you already have https termination proxy(In my case gcloud kubernetes Ingress). If your client comes to your backend with url with "http" schema - he will be redirected to "https" with this filter. – Zufar Muhamadeev Jul 04 '18 at 16:52
5

I managed to make it work with the following. However, I doubt this is supported and it might cause issues in the future.

@Configuration
public class HttpToHttpsRedirectConfig {

    @PostConstruct
    public void startRedirectServer() {
        NettyReactiveWebServerFactory httpNettyReactiveWebServerFactory = new NettyReactiveWebServerFactory(8080);
        httpNettyReactiveWebServerFactory.getWebServer((request, response) -> {
            URI uri = request.getURI();
            URI httpsUri;
            try {
                httpsUri = new URI("https", uri.getUserInfo(), uri.getHost(), 8443, uri.getPath(), uri.getQuery(), uri.getFragment());
            } catch (URISyntaxException e) {
                return Mono.error(e);
            }
            response.setStatusCode(HttpStatus.MOVED_PERMANENTLY);
            response.getHeaders().setLocation(httpsUri);
            return response.setComplete();
        }).start();
    }

}
  • I would suggest doing this on a conditional property like `@ConditionalOnProperty(value="server.port", havingValue = "443")`. – Luke Kroon Nov 06 '19 at 09:05
0

There is a builtin redirectToHttps filter that did the trick for me. It can be used as follows:

@Bean
public SecurityWebFilterChain securityWebFilterChain(final ServerHttpSecurity http) {
    http
        .authorizeExchange()
            .anyExchange()
                .authenticated()
                .and().oauth2Login()
        .redirectToHttps();

    return http.build();
}

Documentation can be found here

Sherwin F
  • 658
  • 7
  • 13