Spring Security

[Security] Form Login 인증 필터 (UsernamePasswordAuthenticationFilter)

cornarong 2021. 10. 4. 21:35

사용자가 로그인을 실행하면 인증처리가 이루어지는데

인증처리를 담당하고 그에 관련된 요청을 처리하는 필터가

UsernamePasswordAuthenticationFilter 이다.

 

UsernamePasswordAuthenticationFilter 내부적으로 각각의 인증처리의 역할에 따라서 여러 클래스를 호출하여 처리하게 되며 전체적인 인증처리의 흐름을 살펴보자.

 

 

1. 인증 처리 전 작업

우선 처음 사용자 인증 시도를 하면 UsernamePasswordAuthenticationFilter가 요청을 받는다

그리고 AntPathRequestMatcher(/login)에서 사용자가 요청한 요청 정보가 매칭이 되는지 확인한다.

(Default는 "/login"이다.)

경로 설정 부분

매칭 실패 시 chain.doFilter으로 호출하고

 

매칭이 성공 시 Authentication객체(인증 객체)를 만들고 로그인 시 입력한 Username과 Password를 해당 객체 안에 저장함으로 인증처리를 준비하게 된다.

 

2. 인증 처리

생성된 인증 객체를 AuthenticationManager에 전달 하고 본격적으로 인증처리를 진행하게 된다.

AuthenticationManagerAuthenticationProvider로 인증 객체를 위임하고 인증 성공과 실패에 따른 결과를 return한다.

 

인증 실패 시 AuthenticationException를 UsernamePasswordAuthenticationFilter으로 반환하여 failureHandler에서 예외처리의 후속작업을 하고

 

인증 성공 시 Authentication객체(인증 객체)를 만들고 회원의 정보권한정보(Authorities)를 저장 하여 AuthenticationManager으로 다시 반환한다.

 

* Authentication객체(인증 객체) 구분

- 인증 처리 전의 Authentication 객체 (로그인 ID + 로그인 Password)

- 인증 처리 후의 Authentication 객체 (회원 정보 + 권한 정보(Authorities))

 

3. 인증 처리 후 작업

 

AuthenticationManagerAuthenticationProvider으로부터 전달 받은 최종적인 인증 결과를 담은 객체(인증 결과 객체)SecurityContext에 저장한다.

(SecurityContext는 인증 객체를 저장하는 보관소로 어디서든 인증 객체를 참조할 수 있도록 설계된 객체이다.)

 

인증 결과 저장 후 SuccessHandler에서는 인증이 성공한 후속 작업들을 처리하게 된다.


추가로 아래 처럼 사용자 보안 설정 클래스의 인증 정책 설정에서 successHandler / failureHandler를 사용하여 인증 실패, 성공 후의 작업을 직접 구현할 수 있다.

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

		// 생략 // 

        .usernameParameter("userId")
        .passwordParameter("passwd")
        .loginProcessingUrl("/login_proc")
        .successHandler(new AuthenticationSuccessHandler() { // 성공 시 후처리
            @Override
            public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException {
            System.out.println("authentication : " + authentication.getName());
            response.sendRedirect("/");
            }
        })
        .failureHandler(new AuthenticationFailureHandler() { // 실패 시 후처리
            @Override
            public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, AuthenticationException exception) throws IOException, ServletException {
            System.out.println("exception : " + exception.getMessage());
            response.sendRedirect("/loginPage");
            }
        })