[61일차]SpringSecurity 흐름, Authentication,SecurityContext

유태형·2022년 7월 25일
0

코드스테이츠

목록 보기
61/77

오늘의 목표

  1. SpringSecurity 흐름
  2. Authentication Filter
  3. Authentication
  4. Aunthentication Manager
  5. Authentication Provider
  6. SecurityContext



내용

SpringSecurity 흐름

  1. 클라이언트로 부터 http 요청이 오면 FilterChainProxy에 들어옵니다. FilterChainProxy는 해당 요청을 처리해줄 AuthenticationFilter의 구현체인 UsernamePasswordAuthenticationFilter를 선택합니다.
  2. AuthenticationFilter가 사용자 정보를 추출하여 usernamepassword를 가지는 UsernamePasswordAuthenticationToken 인증 객체를 생성합니다.
  3. 생성된 인증객체를 AuthenticationManager에게 전달합니다.
  4. AuthenticationManager는 다수의 AuthenticaitonProvider에게 전달하여 유효성 검증및 인증을 위임합니다.
  5. 유효성 검증을 위하여 UserDetailsService로 이동합니다.
  6. loadUserbyUsername() 메서드를 이용하여 데이터베이스에서 해당 데이터를 가지고 와서 UserDetails로 감쌉니다.(존재하지 않을시 UsernameNotFoundException 발생)
  7. AuthenticationProviderUserDetails를 전달합니다.
  8. UserDetailsAuthentication(autories()로 호출)을 AuthenticationManager에 전달합니다.
  9. AuthenticationFilterAuthentcation을 전달합니다.
  10. SecurityContextHolder 안에 SecurityContext 안에 Authentication을 저장합니다.



Authentication Filter

클라이언트로 요청이 오면 제일 먼저 FilterChainProxy에 존재하는 필터를 거치게 됩니다. 필터는 Manager나 provider에서 사용할 수 있는 인증 객체를 만드는 역할을 수행합니다.

클라이언트로부터 요청이 오는 데이터를 읽고 사용자의 usernamepassword를 추출하여 UsernamePasswordAuthentication 인증객체를 생성하는 UsernamePasswordAuthenticationFilter가 대표적으로 존재합니다.

또한 인증을 하지 않은 익명 사용자를 위한 필터도 존재합니다. AnonymousAuthenticationToken 인증객체를 생성하는 AnonymousAuthenticationFilter 필터도 존재합니다.




Authentiactoin

Authentication은 사용자의 인증 정보를 저장하는 인증 객체로써, 인증에 사용한 usernamepassword를 담고 인증을 위해 전달되어 사용됩니다.
인증 후 최종 인증 결과가 SecurityContext에 저장되어 어디서든 참조가 가능합니다.

Authentication 데이터설명
principalusername 혹은 사용자 객체를 저장합니다.
credentials사용자의 비밀번호를 저장합니다.
authorities사용자에게 부여된 권한 목록을 저장합니다.
details인증 부가 정보
authenticated인증 여부

UsernamePasswordAuthenticationFilter가 생성하고 AuthenticationManager가 인증처리를 위해 사용합니다.




AuthenticationManager

AuthenticationManagerAuthenticationFilter로 부터 인증 처리를 명령 받으면 처리가 가능한 AuthenticationProvider를 골라서 인증 처리 작업을 위임합니다. 또 성공을 한다면 다시 필터에게로 Authentication 인증 객체를 전달 합니다.

AuthenticationManager는 인터페이스, ProviderManagerAuthenticationManager를 구현한 구현체 입니다.
ProviderManager는 요건에 맞는 AuthentictaionProvider를 찾아 인증 처리를 위임하는 클래스입니다.
만약 요건에 맞는 적절한 AuthenticatioinProvider를 찾지 못한다면 부모 ProviderManager에서 AuthenticationProvider를 호출할 수 도 있습니다.




Authentication Provider

Authentication Provider는 실제로 인증을 처리합니다. Provider는 2개의 메서드가 존재합니다.

  • authenticate(Authentication) : 실제로 인증을 처리하는 메서드입니다.
  • supports(Authentication) : 해당 Provider가 인증을 처리할 수있는지 여부를 판별합니다.

authenticate(Authentication) 메서드에서 실제로 인증을 처리하게 됩니다. 인증을 위한 비교는 3단계로 이루어 집니다. ID 검증 -> PW검증 -> 부가검증 순으로 이루어 지게 됩니다.

  • 아이디 검증 : UserDetailServiceloadUserByUsername() 메서드를 통해 해당 아이디가 존재하면 userDetail 객체를 반환하고 존재하지 않으면 UserNotFoundException을 반환합니다.
  • 비밀번호 검증 : 반환받은 UserDetail객체로부터 getPassword()메서드로 부터 반환 받은 비밀번호와 Authentication객체의 getPassword()메서드로부터 반환 받은 비밀번호가 일치한지 확인합니다. 보통 보안상 UserDetail객체의 비밀번호는 PasswordEncoder로 비밀번호가 암호화 되어 있습니다.
  • 부가검증 : 사용자가 추가적으로 검증과정을 더 거치게 만들 수 있습니다.

authenticate(Authentication) 메서드의 검증을 모두 통과하면 Authentication 인증 객체를 AuthenticationManager객체에게 전달합니다.




SecurityContext

SecurityContextAuthentication을 저장하고 필요시 꺼내 쓸 수 있는 클래스입니다. 또한 ThreadLocal(Thread마다 할당된 고유 공간)에 저장되어 아무곳에서나 참조가 가능하도록 설계되었습니다.
인증이 완료되면 HttpSession에 저장되어 애플리케이션 전역에서 사용 되어질 수 있습니다.



SecurityContextHolder

SecurityContextHolderSecurityContext를 저장하고 반환할 수 있습니다.

SecurityContext 컨텍스트 = SecurityContextHolder.createEmptyContext();
Authentication 인증객체 = new TestingAuthentication("아이디","비밀번호","ROLE_권한");
context.setAuthentication(인증객체);
SecurityContextHolder.setContext(컨텍스트);

SecurityContextHolder -> SecurityContext -> Authentication 이 저장됨을 알 수 있습니다.




후기

이해해야 하는 클래스나 객체들이 많고 또 구조가 복잡해서 이해도 쉽게 가지 않습니다. 내일도 복습하여 정확히 어떻게 동작하는지 대략적으로 설명된 부분을 확실히 짚어야 되겠습니다.




GitHub

없음!

profile
오늘도 내일도 화이팅!

0개의 댓글