ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • AuthenticationManager와 Authentication
    Spring/Spring 2020. 8. 9. 03:05

     

    • SecurityContextHolder는 Authentication을 담고 있는 곳이며
    • 실제 Authentication을 만들고 인증을 처리하는 인터페이스는 AuthenticationManager이다.

     

     

    AuthenticationManager interface

     

    • AuthenticationManager는 authenticate라는 메서드만을 가지며 
    • 여기서 authentication은 유저가 입력한 username, password 등의 인증정보를 담고 있다.
    • 유효한지 확인 후 UserDetailsService가 return 한 객체를 Principal로 담고 있는 Authentication 객체를 return 해준다.

     

    실제 이러한 인증의 구현체로 ProviderManager을 사용하게 된다.

     

     

    ProviderManager에 Debug을 걸어서 어떠한 과정으로 인증이 되는지 알아보자.

     

     

    • 우선 whitewin / 123으로 계정을 하나 만들고 Sign in을 누르자.
    • 그러면 인증을 위해 ProviderManager로 가게 된다.

     

    • 파라미터로 들어온 authentication에 principal과 credentials 등이 담긴 것을 알 수 있다.
    • 인증은 또 다른 AuthenticationProvider에게 위임하여 진행이 된다.

     

     

    AUthentication 객체

    • Principal : UserDetailsService에서 리턴한 그 객체 ( User )
    • Credentials 
    • GrantedAuthorities

     

    • 최종적으로 유효한 인증인지 확인 후 Authentication 객체를 리턴하게 되며
    • 이 이후로 콘텍스트 홀더를 통해 꺼내서 사용할 수 있게 된다.

     

     


     

    이렇게 AuthenticationManager가 인증을 마친 뒤 Authentication의 행방은 어떻게 될까?

     

    • 어딘가에서 이 인증이 된 Authentication 객체를 Spring Security에 넣어주어야 할 것이다.
    • 최종적으로 인된 Authentication이 SecurityContextHolder로 들어갔기 때문에 우리가 사용 가능하기 때문이다.

     

    크게 2가지 Filter가 Authentication 객체를 SecurityContextHolder에 넣어주게 된다.

     

     

     

     

    간단한 계정 id : whitewin , pw : 123을 만든 후 다음의 코드를 디버깅하여 살펴보면서

    이 authentication은 언제 SecurityContextHolder로 들어가게 되는지 알아보자.

     

     

    1. account 생성 ( whitewin / 123 )

    SecurityContextPersistenceFilter.java

    account를 생성할 때 SecurityContextPersistenceFilter 클래스가 요청을 처리하는 데 사용이 된다.

     

     

    • 조금 더 내려보면 SecurityContextHolder가  매 요청마다 만들어진 Context를 가져오려고 하지만
    • 처음 요청은 인증된 사용자가 없기 때문에 가져오는 게 없는 것을 알 수 있다.
    • 그리고 요청을 다 끝낸다면 Context를 clear 해주는 일을 하고 있다.

     

    2. account 계정을 만들고 Form Login을 한 상황

     

    UsernamePasswordAuthenticationFilter

    • 이번에는 UsernamePasswordAuthenticationFIlter에 걸리게 됐고 Form 인증을 처리하게 된다.
    • 앞에서 보았던 AuthenticationManager가 authenticate 하는 상황이 이곳에서 벌어진다.

     

     

    이렇게 인증을 마치고 객체가 반환되면 어디로 갈까?

     

     

    • 우선 상속을 받았던 부모 FIlter로 간 후 

     

    AbstractAuthenticationProcessingFilter.java
    AbstractAuthenticationProcessingFilter.java
    AbstractAuthenticationProcessingFilter.java

    • 인증이 되었다면 SecurityContextHolder에 들어가는 것을 볼 수 있다.

     

     

    즉 매 요청마다 SecurityContextHolder에 Context를 비워주고 기존에 있다면 SecurityContextHolder 넣어주는 것이

    SecurityContextPersistenceFilter이다.

     

     

    정리:

     

    1. UsernamePasswordAuthenticationFilter

    • 폼 인증 처리를 시큐리티 필터
    • 인증된 Authentication 객체를 SecurityContextHolder에 넣어 주는 필터
    • SecurityContextHolder.getContext(). setAuthentication(authentication)

     

    2. SecurityContextPersisenceFilter

    • SecurityContext를 Http session을 통해 캐시 하며 여러 요청에서 Authentication을 공유하는 필터.

    물론 Spring Security에서 기본적으로 제공해주는 stateful 한 세션 저장을 쓰지 않을 수도 있는데

     

    • 매 요청마다 인증에 필요한 정보를 헤더나 요청 본문에 넣은 후  매번 인증을 통해
    • SpringSecurityContextHolder에 authentication을 넣어주는 Filter를 만들어 stateless 하게 유지할 수도 있다.

     

     

     

    참고 : 인프런(백기선) - 스프링 시큐리티

Designed by Tistory.