Spring security - Change /login default path

Viewed 2071

We want to add spring to security to our spring boot application

The problem is that we have already /login path used already

So currently we can't load spring security default login page which redirect to /login path

We want to keep the spring default login form, just to change the path it uses,

Meaning, using the default behavior/implementation, only the default (form and process) paths need to be changed (without need to create html)

We didn't find any relevant property or code (or answer) to override it

I see in DefaultLoginPageGeneratingFilter the default

 public static final String DEFAULT_LOGIN_PAGE_URL = "/login";

EDIT

Tried the setLoginPageUrl method suggested by @jannis

@Component
public class LoginFormFilter extends DefaultLoginPageGeneratingFilter {
    @PostConstruct
    private void init() {
        setLoginPageUrl("/api/login");
    }
    @Override
    public String getLoginPageUrl() {
        return "/api/login";
    } 
}

But still getting the default login page

Also failed to override using loginPage method

@Override
protected void configure(HttpSecurity http) throws Exception {
 ....formLogin().loginPage("/api/login");
2 Answers

The main issue in overriding default login url is in FormLoginConfigurer because that class is final and all useful configuration methods are final or private. Respectively, I propose to create additional configurer for setting properties in DefaultLoginPageGeneratingFilter class.

public class AdditionalFormLoginConfigurer extends AbstractHttpConfigurer<AdditionalFormLoginConfigurer, HttpSecurity> {

    private String loginPageUrl;
    private String loginProcessingUrl;

    @Override
    public void init(HttpSecurity http) throws Exception {
        DefaultLoginPageGeneratingFilter loginPageGeneratingFilter = http.getSharedObject(DefaultLoginPageGeneratingFilter.class);
        if (loginPageGeneratingFilter == null) {
            return;
        }

        loginPageGeneratingFilter.setFormLoginEnabled(true);
        loginPageGeneratingFilter.setUsernameParameter("username");
        loginPageGeneratingFilter.setPasswordParameter("password");
        loginPageGeneratingFilter.setLoginPageUrl(loginPageUrl);
        loginPageGeneratingFilter.setLogoutSuccessUrl(loginPageUrl + "?logout");
        loginPageGeneratingFilter.setFailureUrl(loginPageUrl + "?error");
        loginPageGeneratingFilter.setAuthenticationUrl(loginProcessingUrl);
    }

    public AdditionalFormLoginConfigurer loginPage(String loginPageUrl) {
        this.loginPageUrl = loginPageUrl;
        return this;
    }

    public AdditionalFormLoginConfigurer loginProcessingUrl(String loginProcessingUrl) {
        this.loginProcessingUrl = loginProcessingUrl;
        return this;
    }
}

And register the class above in the config like this:

private static final String LOGIN_PAGE_URL = "/custom_login_url";
private static final String LOGIN_PROCESSING_URL = "/perform_login";

@Override
protected void configure(HttpSecurity http) throws Exception {
    ...
    .formLogin()
        .loginPage(LOGIN_PAGE_URL)
        .loginProcessingUrl(LOGIN_PROCESSING_URL)
        .permitAll()
    .and()
        .apply(new AdditionalFormLoginConfigurer())
        .loginPage(LOGIN_PAGE_URL)
        .loginProcessingUrl(LOGIN_PROCESSING_URL)
    ...
}

Spring Security is based largely on Spring MVC. So, in order to change the default page (html and url) you need to do a couple of things:

1. Add to your config:

formLogin().loginPage("/whatever/path/to/you/login")

formLogin is the entry-point to customize form-based login behaviour, and loginPage overrides the default form. As stated on the docs:

Specifies to support form based authentication. If FormLoginConfigurer.loginPage(String) is not specified a default login page will be generated.

2. Register a view under that new path to serve your custom form:

registry.addViewController("/whatever/path/to/you/login");

3. Include your new login form (html, thymeleaf, jsp, etc) into your resources.

That should do the trick.

Here you are just overriding the URL and the form. Just keep in mind that here you are not overriding any of the other URLs for the login flow (like loginProcessingUrl).

There is also a good article on Baeldung: https://www.baeldung.com/spring-security-login

Related