Skip to content
Advertisement

Spring security loginProcessingUrl only works on localhost

I have built an application by using Spring Boot and Thymeleaf. My application works as supposed in my localhost, but when I package it as a .war and deploy it in a test tomcat server, it prompts the login page and then either redirects me to the error page or brings me back to the login page.

I have tried multiple things, and I think that there is an issue with the way I am handling the formLogin() inside my SecurityConfig.java class. More specifically, since Tomcat adds the base-url (e.g. from localhost:8080 to serverUrl:8080/reservation) when uploading my app, the loginProcessingUrl class probably fails to identify the “/process-login” class located on the login.html page.

Please find below my SecurityConfig.java class

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    private UserService userService;
    private CustomAuthenticationSuccessHandler customAuthenticationSuccessHandler;
    private AccessDeniedHandler accessDeniedHandler;

    @Autowired
    public SecurityConfig(UserService userService, CustomAuthenticationSuccessHandler customAuthenticationSuccessHandler, AccessDeniedHandler accessDeniedHandler) {
        this.userService = userService;
        this.customAuthenticationSuccessHandler = customAuthenticationSuccessHandler;
        this.accessDeniedHandler = accessDeniedHandler;
    }
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.authenticationProvider(authenticationProvider());
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {

        http
        .authorizeRequests()
        .antMatchers("/login-form-page","/resources/**").permitAll()
        .antMatchers("/", "/new-reservation", "/your-reservations","/all-reservations",
                "/change-password").hasAnyRole("ADMIN","EMPLOYEE","MANAGER")
        .antMatchers("/users","/user-reservations","/arrival-date","/duplicate-reservations","/all-reservations","/registration**")
                .hasAnyRole("ADMIN").and()
        .formLogin()
            .loginPage("/login-form-page")
            .loginProcessingUrl("/process-login")
            .successHandler(customAuthenticationSuccessHandler)
            .permitAll()
        .and()
        .logout()
            .logoutUrl("/login-form-page")
            .permitAll()
        .and()
                .exceptionHandling().accessDeniedHandler(accessDeniedHandler);
    }

    @Override
    public void configure(WebSecurity web) {
        web.ignoring()
                .antMatchers("/resources/**", "/static/**");
    }
    @Bean
    public BCryptPasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }
    @Bean
    public DaoAuthenticationProvider authenticationProvider() {
        DaoAuthenticationProvider auth = new DaoAuthenticationProvider();
        auth.setUserDetailsService(userService); 
        auth.setPasswordEncoder(passwordEncoder());
        return auth;
    }

And here is a small sample of the login.html page.

    <div class="form-container sign-in-container">
        <form id="loginForm" name="regForm" th:action="@{/process-login}"
            method="POST">
                <input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}"/>
                    <h1>Sign In</h1>
                    <!-- Login Error -->
                    <div th:if="${param.error}"
                        class="alert alert-danger  col-xs-10">Wrong email and/or password</div>
    
                    <!-- Logout notify -->
                    <div th:if="${param.logout}"
                        class="alert alert-success 1 col-xs-10">You
                        have been logged out.</div>


All the .html pages are located in

-resources
 -templates

Lastly, the only error I see in the logs is the following

DEBUG o.s.w.s.r.ResourceHttpRequestHandler - Resource not found

Advertisement

Answer

For anyone interested, I managed to solve the above issue. It seems like it was not a misconfiguration in the loginProcessingUrl() class. Instead, the issue was the way a remote server handles the JSESSIONID and csrf. More specifically, what I had to do is

  • Added the following block of code in my SecurityConfig.java
 cookieServerCsrfTokenRepository.setCookieHttpOnly(false);
    http.csrf().csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse());
  • Next, added the block of code below
 @Bean
    public ServletContextInitializer servletContextInitializer(@Value("${secure.cookie}") boolean secure) {
        return new ServletContextInitializer() {

            @Override
            public void onStartup(ServletContext servletContext) throws ServletException {
                servletContext.getSessionCookieConfig().setSecure(secure);
            }
        };
    }

The secure.cookie value needs to be set (in the application.properties to true if you intend to utilise the HTTPs protocol.

Advertisement