[Spring Security] 아키텍처 이해 - 인증(Authentication) 이해하기

식빵·2022년 8월 15일
0
post-thumbnail

이 시리즈에 나오는 모든 내용은 인프런 인터넷 강의 - 스프링 시큐리티 - Spring Boot 기반으로 개발하는 Spring Security - 에서 기반된 것입니다. 그리고 여기서 인용되는 PPT 이미지 또한 모두 해당 강의에서 가져왔음을 알립니다.


인증이라는 것은 서버에 "내가 누구인지"를 알려주는 절차이다.
그런데 이런 인증을 위해서 스프링 시큐리티는 내부적으로 토큰이라는 개념을
사용한다. 이 토큰이라는 게 뭔지, 구조는 어떤지 알아보자.




🥝 토큰(Token)


스프링 시큐리티에서는 인증 정보를 하나의 토큰 개념으로 관리한다.
그래서 우리가 앞서 본 로그인 과정에서도 UsernamePasswordAuthenticationToken 이라는 이름의 클래스를 사용했던 것이다.
앞으로는 토큰이라는 명칭이 나오면 인증과 관련된 거라고 이해하자.

그런데 이런 토큰은 "인증 시"와 "인증 후"에 내부 데이터가 다르다.

  • 인증 시: id, password 정보를 담는다
  • 인증 후: User 객체, 권한 정보를 담는다.

참고로 인증 후에 토큰은 SecurityContext에 저장되어서 전역적으로 참조할 수 있다.

SecurityContextHolder.getContext().getAuthentication();





🥝 토큰의 구조


토큰에는 내부에서 저장하는 것들은 다음과 같다.

  1. principal: 사용자 아이디 혹은 User 객체 저장
  2. credentials : 사용자 비밀번호
  3. authorities : 인증 사용자의 권한 목록
  4. details : 인증 부가 정보
  5. Authenticated : 인증 여부





🥝 토큰의 사용 흐름






🥝 Authentication 인터페이스


  • Authentication 의 구현체들이 모두 "토큰"이라는 이름의 클래스라는 것을 알 수 있다.

  • 내부적으로 다음과 같은 메소드를 갖는다.

    • getAuthorities
    • getCredentials
    • getDetails
    • getPrincipal
    • isAuthenticated
    • setAuthenticated
  • 우리도 직접 이 인터페이스를 구현해서 새로운 토큰을 생성할 수 있다.





🥝 실제 사용 예


실제로 사용 예인 UsernamePasswordAuthenticationToken 의 사용 코드를 확인해보자.
일단 스프링 시큐리티 설정은 아래처럼만 하고 테스트하자.

@Override
protected void configure(HttpSecurity http) throws Exception {

    http
        .authorizeRequests()
        .anyRequest().authenticated()
        .and()
        .formLogin();
}

이렇게 설정하고, 서버 실행하고 브라우저에서 localhost:8080로 접근해보자.
그러면 로그인 페이지가 나올 것이고, 거기서 로그인을 시도하자.


1. AuthenticationFilter.attemptAuthentication

UsernamePasswordAuthenticationFilter.attemptAuthentication 메소드가 실행된다.

이때 UsernamePasswordAuthenticationToken 을 생성하는데,
현재는 인증을 위한 토큰 생성이므로 username, password 만 넣어준다.

이때 사용되는 생성자 코드를 보면 아래와 같다.



2. ProviderManager.authenticate

1번에서 생성된 인증 토큰을 전달받은 이 메소드는 내부적으로 이 토큰을 처리해줄 수 있는
Provider 를 찾게 된다 (if(!provider.supports(toTest))).


참고 사진) UsernamePasswordAuthenticationToken 을 처리해주는 supports 메소드



3. AbstractUserDetailsAuthenticationProvider.authenticate

실제 인증 처리 과정을 처리하게 되는 메소드인데, 정상적으로 인증처리가 되면 맨끝에
createSuccessAuthentication 라는 메소드를 호출한다.

패스워드 인코딩을 한번 해주고 나서 인증 토큰을 생성하는 것을 확인할 수 있다.
그런데 이전과 달리 이번에는 토큰의 생성자에 인자가 더 들어간다.

해당 생성자의 내용을 보면 권한과 관련된 것도 세팅해주는 것을 확인할 수 있다.



4. AbstractAuthenticationProcessingFilter.successfulAuthentication

최종적으로 SecurityContext 에 해당 인증 객체를 저장하는 것을 확인할 수 있다.

profile
백엔드를 계속 배우고 있는 개발자입니다 😊

0개의 댓글