스프링 - 토큰

아침7시개발·2022년 5월 25일
0

스프링

목록 보기
2/6
post-thumbnail

스프링 부트에서 토큰방식 로그인을 구현해보자.
구현은 Spring Security + JWT를 사용할 예정이다.
Spring Security는 강력한 사용자 인증 및 Access 제어 framework이다.

과정

인증(Authentication)은 주체(Principal)의 신원(Identity)을 증명하는 과정이다.

  • 주체는 자신을 인증해달라고 신원 증명 정보(Credential)을 제시한다. 주체가 유저일 경우 Credential은 대개 패스워드이다.
  • 인가(Authorization, 권한 부여)는 인증을 마친 유저에게 권한 Authority을 부여하여 대상 애플리케이션의 특정 리소스에 접근할 수 있게 허가하는 과정이다. 인가는 반드시 인증 과정 이후 수행돼야하며 권한은 롤 형태로 부여하는 것이 일반적이다.
  • 접근통제(Access Control, 접근 제어)는 애플리케이션 리소스에 접근하는 행위를 제어하는 일이다. 따라서 어떤 유저가 어떤 리소스에 접근하도록 허락할지를 결정하는 행위, 즉 접근 통제 결정이 뒤따른다. 리소스의 접근 속성과 유저에게 부여된 권한 또는 다른 속성들을 견주어 결정한다.

FilterChain

Spring Security는 표준 서블릿 필터를 사용한다. 다른 요청들과 마찬가지로 HttpServletRequest와 HttpServletResponse를 사용한다. Spring Security는 서비스 설정에 따라 필터를 내부적으로 구성한다. 각 필터는 각자 역할이 있고 필터 사이의 종속성이 있으므로 순서가 중요하다. XML Tag를 이용한 네임스페이스 구성을 사용하는 경우 필터가 자동으로 구성되지만, 네임스페이스 구성이 지원하지않는 기능을 써야하거나 커스터마이징된 필터를 사용해야 할 경우 명시적으로 빈을 등록 할 수 있다.

클라이언트가 요청을 하면 DelegatingFilterProxy가 요청을 가로채고 Spring Security의 빈으로 전달한다. (tmi. DispatcherServlet보다 먼저 실행 됨) 이 DeletgatingFilterProxy는 web.xml과 applicationContext 사이의 링크를 제공한다. DelegatingFilterProxy는 한 마디로 Spring의 애플리케이션 컨텍스트에서 얻은 Filter Bean을 대신 실행한다. 그러니 이 Bean은 javax.servlet.Filter를 구현해야한다.

Spring Security Filter Chain는 아래와 같이 다양하며 커스마이징이 가능하다.

  • SecurityContextPersistentFilter : SecurityContextRepository에서 SecurityContext를 가져와서 SecurityContextHolder에 주입하거나 반대로 저장하는 역할을 한다.
  • LogoutFilter : logout 요청을 감시하며, 요청시 인증 주체(Principal)를 로그아웃 시킨다.
  • UsernamePasswordAuthenticationFilter : login 요청을 감시하며, 인증 과정을 진행한다.
  • DefaultLoginPageGenerationFilter : 사용자가 별도의 로그인 페이지를 구현하지 않은 경우, 스프링에서 기본적으로 설정한 로그인 페이지로 넘어가게 한다.
  • BasicAuthenticationFilter : HTTP 요청의 (BASIC)인증 헤더를 처리하여 결과를 SecurityContextHolder에 저장한다.
  • RememberMeAuthenticationFilter : SecurityContext에 인증(Authentication) 객체가 있는지 확인하고 RememberMeServices를 구현한 객체 요청이 있을 경우, RememberMe를 인증 토큰으로 컨텍스트에 주입한다.
  • AnonymousAuthenticationFilter : 이 필터가 호출되는 시점까지 사용자 정보가 인증되지 않았다면 익명 사용자로 취급한다.
  • SessionManagementFilter : 요청이 시작된 이후 인증된 사용자인지 확인하고, 인증된 사용자일 경우 SessionAuthenticationStrategy를 호출하여 세션 고정 보호 매커니즘을 활성화 하거나 여러 동시 로그인을 확인하는 것과 같은 세션 관련 활동을 수행한다.
  • ExceptionTranslationFilter : 필터체인 내에서 발생되는 모든 예외를 처리한다.
  • FilterSecurityInterceptor : AccessDecisionManager로 권한부여처리를 위임하고 HTTP 리소스의 보안 처리를 수행한다.

스프링 시큐리티의 구조

  1. 사용자가 입력한 사용자 정보를 가지고 인증을 요청한다.(Request)
  2. AuthenticationFilter가 이를 가로채 UsernamePasswordAuthenticationToken(인증용 객체)를 생성한다
  3. 필터는 요청을 처리하고 AuthenticationManager의 구현체 ProviderManager에 Authentication과 UsernamePasswordAuthenticationToken을 전달한다.
  4. AuthenticationManager는 검증을 위해 AuthenticationProvider에게 Authentication과 UsernamePasswordAuthenticationToken을 전달한다.
  5. 이제 DB에 담긴 사용자 인증정보와 비교하기 위해 UserDetailsService에 사용자 정보를 넘겨준다.
  6. DB에서 찾은 사용자 정보인 UserDetails 객체를 만든다.
  7. AuthenticationProvider는 UserDetails를 넘겨받고 비교한다.
  8. 인증이 완료되면 권한과 사용자 정보를 담은 Authentication 객체가 반환된다.
  9. AuthenticationFilter까지 Authentication정보를 전달한다.
  10. Authentication을 SecurityContext에 저장한다.

Authentication정보는 결국 SecurityContextHolder 세션 영역에 있는 SecurityContext에 Authentication 객체를 저장한다. 세션에 사용자 정보를 저장한다는 것은 전통적인 세션-쿠키 기반의 인증 방식을 사용한다는 것을 의미한다.

출처

목포
북항

profile
쉬엄쉬엄하는 개발자

0개의 댓글