Spring redirect happening to "http://...../login" instead of "https://...../login"

Viewed 1462

I have deployed a war file generated by spring boot application using oauth2 for single sign on using Azure App service (https only).

When I browse to the home page, the home page loads with a login button. On clicking the login button a redirect is happening to "http://..../login" (/login is the default sso login path) Since my app service is https only, the http url does not work.

I have tried the redirect_uri settings in the application.property file, but it is not helping. Has anybody faced this problem? How can it solved?

I found a similar issue mentioned here

2 Answers

This problem happens when your Tomcat server is behind a proxy. The HTTPS requests terminate at the proxy and the proxy then uses HTTP protocol to communicate to your Tomcat server. You will face this if you deploy your code on cloud providers like Azure (App Service), etc.

For anyone facing this problem, here is the solution:

in application.properties file, add the following. Note: some of the properties have different names in Spring Boot 2.* versions.

security.oauth2.client.pre-established-redirect-uri=https://yourappurl.net/login
security.oauth2.client.registered-redirect-uri=https://yourappurl.net/login
security.oauth2.client.use-current-uri=false
server.tomcat.remote-ip-header=x-forwarded-for
server.tomcat.protocol-header=x-forwarded-proto
server.tomcat.use-relative-redirects=true
server.use-forward-headers=true
server.tomcat.internal-proxies=.*

In your SpringBootApplication class, add the following bean. With Spring Boot <= 2.1.x you had to provide a ForwardedHeaderFilter-Bean. Since Spring Boot 2.2.0 you don't have to do this anymore.

import org.springframework.core.Ordered;
import org.springframework.web.filter.ForwardedHeaderFilter;
@Bean
FilterRegistrationBean<ForwardedHeaderFilter> forwardedHeaderFilter() {
    final FilterRegistrationBean<ForwardedHeaderFilter> filterRegistrationBean = new FilterRegistrationBean<ForwardedHeaderFilter>();
    filterRegistrationBean.setFilter(new ForwardedHeaderFilter());
    filterRegistrationBean.setOrder(Ordered.HIGHEST_PRECEDENCE);
    return filterRegistrationBean;
}

Add the following line in configure method of your AppConfiguration class:

http.requiresChannel().anyRequest().requiresSecure();

For official info visit this page.

Ranbir has well explained the usecase where someone will face this problem.

I didnt have to add any additional properties to my springboot project. I just had to add ForwardedHeaderFilter as part of spring configuration and mentions the urls where I want this filter to act on x-forwarded header:

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import javax.servlet.DispatcherType;
import org.springframework.core.Ordered;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.web.filter.ForwardedHeaderFilter;

import java.security.Security;
import java.util.Arrays;

@SpringBootApplication(scanBasePackages = {"com.abc.xyz"})
public class Application {

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
        log.info("--- Security Overrides ---");
        log.info("networkaddress.cache.ttl =" + Security.getProperty("networkaddress.cache.ttl"));
    }

    @Bean
    public FilterRegistrationBean<ForwardedHeaderFilter> forwardedHeaderFilter() {
        ForwardedHeaderFilter filter = new ForwardedHeaderFilter();
        FilterRegistrationBean<ForwardedHeaderFilter> registration = new FilterRegistrationBean<>(filter);
        registration.setDispatcherTypes(javax.servlet.DispatcherType.REQUEST, DispatcherType.ASYNC, DispatcherType.ERROR);
        registration.setOrder(Ordered.HIGHEST_PRECEDENCE);
        registration.setUrlPatterns(Arrays.asList("/app/*", "/ping", "/oauth2/authorization/callback", "/oauth/callback"));
        return registration;
    }

}

Here are some useful references to follow: https://tomgregory.com/spring-boot-behind-load-balancer-using-x-forwarded-headers/

https://docs.spring.io/spring-framework/docs/current/reference/html/web.html#filters-forwarded-headers

https://docs.spring.io/spring-boot/docs/2.0.1.RELEASE/reference/htmlsingle/#howto-enable-https

Related