관리 메뉴

bright jazz music

[Spring security] 1.4 Form Login 인증 필터 : UsernamePasswordAuthenticationFilter 본문

Framework/Spring Security

[Spring security] 1.4 Form Login 인증 필터 : UsernamePasswordAuthenticationFilter

bright jazz music 2022. 9. 9. 23:29

 

usernamePasswordAuthenticationFilter : 로그인 폼 인증 처리. formLogin()과 그 하위 API들을 설정하면 인증처리가 초기화 되면서 로그인 인증처리가 작동할 수 있도록 시큐리티가 구성작업을 한다. 실제 사용자가 로그인을 하게 되면 인증처리를 담당하고 그 요청을 처리하는 필터가 이 필터이다. 이 필터가 내부적으로, 각  인증처리 역할에 따라서 여러 클래스를 활용하여 인증 처리를 하게 된다.

 

인증처리 과정

 

- 사용자 요청 

- 필터가 그 요청을 받는다.

- AntPathRequestMatcher() 메서드를 사용해서 요청 정보가 매칭되는지 확인. 기본값을 /login. loginProcessingUrl() 이 값이 변경되면 그에 맞게 AntPathRequestMatcher()도 값을 변경한다.

- 이 정보가 맞으면 Authentication 필터로 넘어간다. Authentication 객체를 만들어서 객체 안에  사용자가 로그인 시 입력한 네임과 패스워드 값을 저장해서 인증처리를 AuthenticationManager클래스에 맡긴다.

- AuthenticcationManager는 Authentication 필터로부터 Authentication 객체를 전달 받는다. 이 클래스는 AuthenticationProvider 객체를 내부적으로 가지고 있다. 그중 하나를 선택해서 인증 처리를 위임한다. Authentication 프로바이더가 실제 인증처리를 담당하는 클래스이다. 이 클래스가 인증 성공/ 실패 결과를 리턴한다.

- 인증 실패하는 경우 AuthenticationException을 반환하는데 목적지는 UsernamePasswordAuthenticationFilter 이다. 여기에 도착하여 후속작업을 하면 된다.

- 만약 인증에 성공하면 AuthenticationProvider가 Authentication 객체를 만든다. 그리고 인증에 성공한 결과(정보)를 그 객체 안에 저장한다. 그걸 다시 AuthenticationManager에게 리턴한다.

-AuthenticationManager는 인증 성공 정보가 담겨 있는 Authentication 객체를 다시 Authentication 필터에[ 전달한다.이 객체 안에는 인증에 성공한 user 객체와 권한 정보를 가지고 있는 Authorities 객체를 가지고 있다.

-그리고 이 인증 객체를 SecurityContext 클래스에 저장한다. SecurityContext는 인증 객체를 보관하는 보관소이다. 나중에는 세션에도 저장되어  사용자가 시큐리티 컨텍스트 안에서 이 객체를 전역적으로 Autrhentication 객체에 접근할 수 있도록 처리해 준다.

- 그리고 성고 잉후에 successHandler로 넘긴다.

 

 

 

소스코드로 살펴보기

 

서버기동 후 접근

- AbstractAuthenticationProcessingFilter.java

- 로그인 페이지 인증 시도 -> attemptAuthentication(request, response)

이 메서드는 usernamePasswordAuthenticationFilter에 존재한다.

- 여기서 인증 객체를 생성한다. (Authentication객체)

-이걸 ProviderManager(AuthenticationManager의 구현체)에게 인증 처리를 맡긴다.

- 매니저는 이걸 자기가 가지고 보관하고 있는 AuthenticationProvider에게 인증처리를 위임한다.

AuthenticationProvider가 인증에 성공하면 다시 Authentication 객체를 생성한다. 이 안에는 인증에 성공한 유저 객체 정보와 권한 정보가 저장된다.(principal, authentication.getCredentials(), user.getAuthorities())

- 이 객체는 다시 providerManager에게 반환된다.

- providerManager는 인증 결과를 자신을 호출한 usernamePasswordAuthenticationFilter에게 반환한다.

- 이 필터는 authResult(성공정보가 담긴 객체)를 securityContext에 저장한다.(SecurityContextHolder.getContext().setAuthentication(authResult))

이 구문을 가지고 우리가 인증 객체를 장소에 상관 없이 전역적으로 참조할 수 있다. 아래와 같은 구문을 사용하면 말이다.

SecurityContextHolder.getContext().getAuthentication()

 

- 그리고 이후에 SuccessHandler 호출해서 그 후의 작업들을 처리한다.

 

여기까지가 인증필터가 사용자의 인증 요청을 받고 인증처리를 하는 과정이다.

 

 

 

FilterChainProxy.java

이클래슨느 필터들을 관리하는 Bean이다. 관리하는 필터는 아래와 같다.

필터 어떤 것들은 스프링 시큐리티가 초기화되면서 생성된다. 그리고 우리의 설정 클래스인 SecurityConfig에서 우리가 설정했을 때 생성되는 것들도 있다. 예를 들어 .formLogin() api를 호출하면 usernamePasswordAuthenticationFilter가 생성되며 작동한다. 또한 이 필터들은 순서들은 순서대로 사용된다.

 

따라서 FilterChainProxy 클래스가 사용자의 요청을 가장 먼저 받고 각각의 필터 클래스들을 호출하면서 인증/인가 처리를 하는 구조이다.

Comments