프로젝트 인증로직 Description

2021. 11. 28. 19:39학습일지

인증 방식

Token Based Authentication

  • 가장 보편적인 방식은 세션을 활용하여, 세션 ID를 쿠키에 저장하고, 쿠키의 세션 ID를 통해, 세션 서버에 인증 정보를 조회하여, 사용자의 요청을 검증하는 방식이라 할 수 있다.
  • 하지만, 모바일 플랫폼(android 혹은 ios 기반 애플리케이션)의 비중이 증가하고 있는 상황에서, 여러 플랫폼을 받아들일 수 있는 api가 요구되는 경우가 많을거라 판단하여, 헤더에 토큰 키를 포함하여, 토큰 키를 통해 세션 서버에 인증정보를 조회하는 방식을 채택하였다.

JWT와 다른점은?

  • JWT의 경우, `Bearer *` 방식으로, 인증에 필요한 정보를 `Claim`에 포함하여, 인코딩 알고리즘을 적용하여 `sign` 하는 방식으로, 헤더에 포함하는 키 자체에 인증정보가 포함되어 있다.
    • 때문에 JWT는 일반적으로는 헤더 만으로도 요청을 검증할 수 있으므로 세션 서버가 필요가 없다.
    • 그러나, 너무 많은 `claim`을 포함하면, 헤더에 포함한 키의 길이가 길어지고, 결과적으로는 인증을 검증하는 과정이 길어진다.
    • 또한 `sign` 알고리즘은 복호화가 어렵지 않아서, 탈취당하기 쉬우며, 클라이언트 단에서 인증이 확정되기 때문에, 만약, JWT의 유효기간이 무한대라면, 탈취자는 영원히, 사용자의 인증정보를 간직할 수 있다.
  • 일반적인 Token Based Authentication의 경우, 토큰 키 자체는 무의미한 문자열의 조합이다.
    • 따라서, 인증정보를 얻기 위해서는 토큰 키를 통해 세션 서버에 인증 정보를 조회해야 한다.
    • 토큰키를 탈취 당하더라도, 인증 정보는 세션 서버에서 관리하기 때문에, 관리자가 인위적으로, 혹은 코드를 통해, 자동으로 비활성화 시킬 수 있다.
    • 또한 토큰 키를 통해, 조회할 수 있는 인증 정보를 인위적으로 조절할 수 있기 때문에, 민감한 정보는 제외할 수 있다.

주요 기술적 로직 description

Provider & Service

![my_authentication_flow drawio](https://user-images.githubusercontent.com/81374655/143472435-c5dbed10-57b6-48ea-8a47-4ad6fde97520.png)

  1. `Manager` -> `Provider`
    • `AuthenticationManager`를 통해, 커스터마이징한 `Provider`에 인증 로직을 위임
  2. `Provider` -> `Service`
    • 로그인 시도시 입력받은 아이디/비밀번호를 통해, 인증 시도
  3. `Service` -> `Provider`
    • 인증 성공 시, 토큰 키와 인증 정보를 생성하여, 세션 서버에 저장한다.
  4. `Provider` -> `Manager`
    • 생성된 인증 정보를 다시 `Manager`로 보내어 `SecurityFilterChain`을 거쳐 사용자의 로그인 요청에 대한 응답을 검증한다.
    • 생성된 인증 정보는 `SecurityContext` 에 포함할 수 있다.

토큰 키와 인증 정보 생성 로직은 아직 구체화 되어있지 않은 상황이다.

리소스 제어를 위한 CustomAuthFilter

![AccessWithAuthToken drawio](https://user-images.githubusercontent.com/81374655/141892304-79932c28-91ac-43cd-8656-0cecd83ed76c.png)

가장 보편적인 방식은 쿠키의 세션ID를 조회하여, 인증 정보를 조회하는 것이다. 하지만, 위에서 설명했듯이, 여러 플랫폼을 받아들이기 위해 Token Based Authentication 방식을 채택했다. 인증이 필요한 리소스 요청의 경우, Session이 아니라, 커스터마이징된 Token을 통해 인증 상태를 검증하는 로직이 필요하므로, 위의 플로우 차트와 같은 로직을 적용한 커스텀 필터를 구현하여, `SecurityFilterChain`에 포함하였다.