Spring Security의 기능들을 최대한 사용하면서도, api 환경에 맞지 않는 몇몇 설정을 제외하여 설정해본 글입니다.
Spring Security의 로그인 처리를 작성하다 보니 마음에 걸리는 게 있었습니다.
'사용하지도 않을 /login
페이지를 접근하지 못 하게 막을 것인가?'였는데요.
해당 페이지를 막아두는 것보다, 아예 생성조차 되지 않으면서도 formLogin을 살리는 방법에 대해 작성해 보도록 하겠습니다.
@EnableWebSecurity
@EnableMethodSecurity
@Configuration
public class SecurityConfig {
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
...
http.formLogin(formConfig -> {
formConfig.usernameParameter("loginId");
formConfig.successHandler(successHandler());
formConfig.failureHandler(failureHandler());
});
...
http.exceptionHandling(exceptionHandleConfig -> exceptionHandleConfig.authenticationEntryPoint(
new HttpStatusEntryPoint(HttpStatus.UNAUTHORIZED)));
...
return http.build();
}
http.exceptionHandling(exceptionHandleConfig -> exceptionHandleConfig.authenticationEntryPoint(
new HttpStatusEntryPoint(HttpStatus.NOT_FOUND)));
바로 해당 코드가 수행해 줍니다.
정확히는, 해당 설정이 되어 있으면 login page가 생성되지 않습니다.
이 또한 코드로 살펴보겠습니다.
public void configure(H http) {
AuthenticationEntryPoint authenticationEntryPoint = null;
ExceptionHandlingConfigurer<?> exceptionConf = http.getConfigurer(ExceptionHandlingConfigurer.class);
if (exceptionConf != null) {
authenticationEntryPoint = exceptionConf.getAuthenticationEntryPoint();
}
if (this.loginPageGeneratingFilter.isEnabled() && authenticationEntryPoint == null) {
this.loginPageGeneratingFilter = postProcess(this.loginPageGeneratingFilter);
http.addFilter(this.loginPageGeneratingFilter);
LogoutConfigurer<H> logoutConfigurer = http.getConfigurer(LogoutConfigurer.class);
if (logoutConfigurer != null) {
http.addFilter(this.logoutPageGeneratingFilter);
}
}
}
login 페이지를 설정하도록 돕는 곳이 이 곳이며, loginPageGeneratingFilter 클래스가 로그인 페이지를 생성합니다.
if문을 보시면 loginPageGeneratingFilter가 설정이 되어 있고, authenticationEntryPoint가 지정되지 않은 경우에 해당 필터를 add하도록 코드가 작성된 것을 확인하실 수 있습니다.
우리는 이전의 코드에서 authenticationEntryPoint를 설정했기에, loginPageGeneratingFilter가 추가되지 않아 login 페이지가 생성되지 않습니다.
login 페이지는 유저가 로그인하는 것을 도울 수 있습니다. 그러나 해당 로그인 페이지를 마주하는 대부분의 상황은 유저가 로그인하지 않은 채 인증이 필요한 url에 접근할 때입니다.
즉, UNAUTHORIZED한 상황에서 로그인 페이지를 보여주는 것으로 '너는 로그인을 통해 인증받아야 해'라고 알려주는 방식이라 볼 수 있죠.
우리는 UNAUTHORIZED한 상황의 해결책으로 401을 반환하도록 설정했고, 이는 login 페이지 대신 401을 반환하겠다고 선언한 것과 같다고 볼 수 있습니다.