[Spring Boot] Spring Security 로그인 시 405 에러 이슈 (Request method 'POST' not supported)

개요

Spring Security의 SecurityFilterChain을 활용한 기본 로그인(formLogin)에서 로그인을 처리할 때 405 이슈가 발생했다.

 

경과

    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        http
        .authorizeRequests()
            .anyRequest().permitAll()
            .and()
        .formLogin()
            .loginPage("/user/login")
            .usernameParameter("username")
            .passwordParameter("password")
            .successForwardUrl("/")
            .permitAll()
            .failureUrl("/user/login?notify=fail") 
            .and()
        .logout()
            .logoutRequestMatcher(new AntPathRequestMatcher("/user/logout", "GET"))
            .logoutSuccessUrl("/")
            .permitAll()        
            .and()
        .csrf().csrfTokenRepository(csrfTokenRepository());
        
        return http.build();
    }

SecurityFilterChain 코드

 

Spring Security는 위와 같이 설정했다. 간단하게 로그인을 하면 루트 URL로 Redirect하고, 로그아웃도 마찬가지로 설정한다. 

 

.w.s.m.s.DefaultHandlerExceptionResolver : Resolved [org.springframework.web.HttpRequestMethodNotSupportedException: Request method 'POST' not supported]

 

Security 인증 처리는 성공적으로 됐지만, 이후 Redirect 하는 과정에서 계속 405 이슈가 발생했다. 

 

해결

    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        http
        .authorizeRequests()
            .anyRequest().permitAll()
            .and()
        .formLogin()
            .loginPage("/user/login")
            .usernameParameter("username")
            .passwordParameter("password")
            .defaultSuccessUrl("/")
            .permitAll()
            .failureUrl("/user/login?notify=fail") 
            .and()
        .logout()
            .logoutRequestMatcher(new AntPathRequestMatcher("/user/logout", "GET"))
            .logoutSuccessUrl("/")
            .permitAll()        
            .and()
        .csrf().csrfTokenRepository(csrfTokenRepository());
        
        return http.build();
    }

 

 

이는 매우 단순한 문제였는데, successFowordUrl 이라는 함수가 단순히 Redirect하는 것이 아니고, LoginSuccessHandler 처럼 로그인 이후의 로직을 처리할 URL로 POST 요청을 하기 때문이었다.  단순히 Redirect시키고 싶으면 defaultScuccessUrl 이라는 함수를 활용하면 된다. 아예 아무것도 설정하지 않으면 자동으로 루트 URL (/)로 Redirect한다.