이 글은 정수원님의 Infrean 강의를 학습한 내용을 정리하여 작성합니다.
Form 인증 - CustomAuthenticationSuccessHandler
- Form 인증 방식에서 제공해주는 successHandler API를 인터페이스를 통해 직접 구현한다.
구현
CustomAuthenticationSuccessHandler
- 스프링 시큐리티는 기본 구현체인 SimpleUrlAuthenticationSuccessHandler를 제공한다.
- SimpleUrlAuthenticationSuccessHandler를 상속받아 CustomAuthenticationSuccessHandler가 동작하도록 한다.
- 요청 캐시 객체를 사용해 사용자가 인증 후 이동할 페이지로 보내주도록 한다.
- ex) 권한이 없는 익명사용자가 USER 권한이 필요한 마이페이지에 접근하고자 할때 인증 예외가 발생해 로그인 페이지로 이동하게 된다.
익명사용자가 인증을 수행하면 요청 캐시로 마이페이지를 기억하고 인증에 성공하면 마이페이지로 이동시켜주는 작업을 수행한다.
- ex) 권한이 없는 익명사용자가 USER 권한이 필요한 마이페이지에 접근하고자 할때 인증 예외가 발생해 로그인 페이지로 이동하게 된다.
@Component
public class CustomAuthenticationSuccessHandler extends SimpleUrlAuthenticationSuccessHandler {
private RequestCache requestCache = new HttpSessionRequestCache();
private RedirectStrategy redirectStrategy = new DefaultRedirectStrategy();
@Override
public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException {
setDefaultTargetUrl("/");
SavedRequest savedRequest = requestCache.getRequest(request, response);
// 사용자가 권한이 필요한 자원에 접근해 인증 예외가 발생해 인증을 처리하는 것이 아닌 경우
// SavedRequest 객체가 생성되지 않는다.
if (savedRequest != null) {
String targetUrl = savedRequest.getRedirectUrl();
redirectStrategy.sendRedirect(request, response, targetUrl);
} else {
redirectStrategy.sendRedirect(request, response, getDefaultTargetUrl());
}
}
}
- 사용자가 인증 예외가 발생해 인증을 처리하는 경우가 아니면 SavedRequest 객체가 생성되지 않으므로 savedRequest가 null일 경우와 아닌 경우를 구분해 처리한다.
- savedRequest가 null이 아닌 경우 인증 이전 이동하고자 했던 URL를 조회해 해당 URL로 이동시킨다.
- savedRequest 값이 null인 경우 기본 URL인 루트 페이지로 이동시킨다.
- 이때 기본 URL은 위에서 변경시킬 수 있다.
참고
위에서 오버라이딩한 onAuthenticationSuccess 함수에서 파라미터로 받아온 request, authentication 객체를 이용해 정책이나 설계에 따라 다양한 Form 인증 성공 후 여러 작업을 수행할 수 있다.
ex) request 객체로부터 session을 조회해 작업을 수행한다.
ex) 이때 authentication 객체는 최종 인증에 성공하고 생성된 Authentication 객체이다.
이러한 authentication 객체에서 인증 관련 여러 데이터를 참고해서 작업을 수행할 수도 있다.
SecurityConfig
- Form 인증 방식 수행 후 우리가 생성한 SuccessHandler가 정상적으로 수행되도록 설정을 추가한다.
@Configuration
@EnableWebSecurity
public class SecurityConfig {
@Autowired
private AuthenticationSuccessHandler customAuthenticationSuccessHandler;
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
.authorizeHttpRequests((authz) -> authz
.antMatchers("/", "/users").permitAll()
.antMatchers("/mypage").hasRole("USER")
.antMatchers("/messages").hasRole("MANAGER")
.antMatchers("/config").hasRole("ADMIN")
.anyRequest().authenticated()
)
.formLogin()
.loginPage("/login")
.loginProcessingUrl("/login_proc")
.authenticationDetailsSource(authenticationDetailsSource)
.defaultSuccessUrl("/")
.successHandler(customAuthenticationSuccessHandler)
.permitAll();
return http.build();
}
}
실행
로그인 링크를 클릭한 경우 (인증 예외가 발생하지 않은 경우)
- 다음과 같이 우리가 직접 구현한 onAuthenticationSuccess 함수가 호출되는데 savedRequest 값이 null인 것을 확인할 수 있다.
- 인증이 최종적으로 수행되면 기본 루트 페이지로 이동하는 것을 확인할 수 있다.
마이페이지에 접근하고자 하는 경우 (인증 예외가 발생)
- savedRequest 객체가 생성된다.
- 최종 인증에 성공하면 마이페이지로 이동하는 것을 확인할 수 있다.
'스프링 시큐리티 > 실전프로젝트 - 인증 프로세스 Form 인증 구현' 카테고리의 다른 글
인증 거부 처리 - Access Denied (0) | 2023.02.12 |
---|---|
인증 실패 핸들러: CustomAuthenticationFailureHandler (0) | 2023.02.12 |
인증 부가 기능 - WebAuthenticationDetails, AuthenticationDetailsSource (0) | 2023.02.12 |
로그아웃 및 인증에 따른 화면 보안 처리 (0) | 2023.02.12 |
커스텀 로그인 페이지 생성하기 (0) | 2023.02.11 |