JWT를 이용하여 인증/인가를 구현하는 과정에서 고려해야할 사항에 대해서 정리하고 이에 따른 구현방법을 정리해보고자 합니다. 구현하려는 제품 또는 업무의 특성에 따라서 본 내용을 달라질 수 있으니 참고용으로 읽어주시기 바랍니다.
제품의 특성
JWT를 도입하려는 제품은 관제 및 관리 시스템으로 인증된 사용자만이 접근할 수 있어야 합니다. 또한, 각 사용자의 권한(사용자, 관리자, 중간 관리자 등)에 따라 접근할 수 있는 메뉴 및 행위가 차등 부여됩니다. 또한, 인증된 사용자는 인증시각, 접근한 페이지의 진입/진출 시각을 관리해야하고 로그아웃 시각도 보안정책에 의해 관리되어져야 합니다.
- 사용자의 권한에 따른 접근 가능한 페이지의 제한 필요
- 인증된 사용자의 인증시각, 인증만료시각, 접속한 페이지의 진입/진출 기록 관리 필요
- 같은 계정의 중복 로그인 허용/비허용 정책에 따른 동시성 처리 필요
현 제품의 인증/인가의 문제점
- 세션 클러스터링에 따른 서버 관리의 어려움
- 레디스에 정상적으로 세션 만료에 따른 이벤트가 제대로 동작되지 않음
JWT 도입의 판단 근거
JWT의 장점
- JWT 의 주요한 이점은 사용자 인증에 필요한 모든 정보는 토큰 자체에 포함하기 때문에 별도의 인증 저장소가 불필요
- 쿠키를 전달하지 않아도 되므로 쿠키를 사용함으로써 발생하는 취약점이 미발생
- URL 파라미터와 헤더로 사용
- 트래픽 대한 부담이 낮음
- REST 서비스로 제공 가능
- 내장된 만료 처리
- 독립적인 JWT
JWT의 단점
- Self-contained: 토큰 자체에 정보를 포함하여 민감한 정보에 대한 노출 취약점
- 토큰 길이: 정보가 많아질수록 토큰의 길이가 늘어나 네트워크에 부하발생 가능
- Payload 인코딩: 페이로드(Payload) 자체는 암호화 된 것이 아니라, Base64로 인코딩된 정보로 Base64 디코딩하면 데이터를 볼 수 있으므로, JWE로 암호화하거나 Payload에 중요 데이터 배제 필요
- Stateless: JWT는 상태를 저장하지 않기 때문에 한번 만들어지면 제어가 불가능. 즉, 토큰을 임의로 삭제하는 것이 불가능하므로 토큰 만료 시간 설정이 필수적임
- Tore Token: 클라이언트 측에서 토큰 관리. 토큰을 특정 저장소에 저장 필요
JWT 도입의 필요성
- 서버의 부하가 없는 인증/인가 솔루션 도입필요
- ID/PW기반의 인증 외에 다양한 인증 수단(소셜 로그인, IAM연동 등)의 추가도입 검토
JWT 운영 정책 수립 전 고려사항
- JWT 운영 정책 수립 전 질의사항
- 접근토큰(액세스 토큰), 갱신토큰(리프레시 토큰)의 사용여부
# 접근토큰, 갱신토큰 사용
∵ 갱신토큰의 통한 접근토큰의 만료에 따른 권한 상실 제거 - 접근토큰, 갱신토큰의 내용과 유효시간
# 접근토큰 : 15분
# 갱신토큰 : 30일
# 갱신토큰 만료시 재인증 - 토큰 내용 암호화
# 중요 데이터(?)는 암호화, 알고리즘 정의 필요 - 저장하는 위치 프런트 : 쿠키 또는 Local Storage
# 쿠키에 저장 httpOnly, Secure
∵ Local Storage의 경우 Javascript를 통한 XSS 공격가능
∵ 쿠키의 경우 CSRF 공격이 가능하나 CSRF 토큰을 사용하겨 취약점 최소화 - 저장하는 위치 백그라운드 : 데이터베이스 또는 레디스
# 데이터베이스, 레디스에 저장 필요
# 레디스 : 추가 서버구성 및 가용성 유지를 위한 클러스터링/다중화구성 필요. 관리 리스스 필요
# 데이터베이스 : 블랙리스트를 사용한다면 접근 토큰의 검증시마다 데이터베이스 접근 필요(JWT의 장점 상실됨) - - 토큰의 블랙리스트 사용여부
# 접근토큰의 블랙리스트 사용하지 않음
# 갱신토큰의 블랙리스트 사용(접근토큰의 갱신시 갱신토큰의 유효성만 체크)
# 블랙리스트 또는 데이터베이스에서 갱신토큰 삭제 - 접근토큰 만료시 자동 갱신여부
# 만료시 갱신토큰이 유효하면 자동 갱신 - 로그아웃 처리
# 접근토큰 삭제 및 데이터베이스에서 갱신토큰 삭제 - 갱신토큰 만료 처리
# 정해진 시각(접근토큰 유효시간, 15분)마다 배치를 수행하여 접근토큰의 갱신시각이 정해진 시각 이상이면 만료처리
# 데이터베이스에서 삭제 - 장기간 접속하지 않는 사용자의 로그아웃 처리(접근 기록 관리를 위한)
# 배치를 통한 정기적인 미사용 토큰의 만료처리 - 자동 로그인 사용여부
# 배치를 통해 삭제된 갱신토큰이 아닌 경우에는 자동 접근권한 부여 - 토큰의 필요없는 페이지의 접근 처리
# Spring Framework 내에 예외 페이지 추가/관리 - 동시 접속 처리
# 데이터베이스에 접속자의 정보와 갱신토큰을 관리
# 동시 접속을 허용하지 않을 경우 기존 갱신토큰의 만료처리 또는 로그인 배제 - 강제 만료 또는 로그아웃 처리 블랙리스트 처리
# 접근토큰의 경우 강제처리 만료처리 불명확
# 갱신토큰의 만료처리 또는 삭제처리를 통한 블랙리스트 처리 - 서명 키(대칭키, RSA 또는 사설 인증서, 공인 인증서)
# RSA 2048을 통한 공개키 알고리즘을 통한 서명관리 - 서명 키 관리 정책
- 갱신 주기(정기, 비정기)
# 비정기 : 보안상 필요 - 키의 만료 처리
# 키의 상태관리를 통해 유효한 키관리
# 토큰의 서명 가능 키, 유효성 검증가능 키, 사용중지된 키 - 이전 서명키의 유효성 처리
# 키의 검증가능 상태/ 서명가능 상태인 것만 유효성 처리
- 갱신 주기(정기, 비정기)
- 암호 키 사용여부 및 관리 정책
# 암호화여부 논의 필요
# 대칭키/비대칭키 사용여부 논의 필요 - 데이터베이스 테이블
# 갱신 토큰 관리
# 키 관리
# 블랙리스트 관리
기타
https://docs.authlib.org/en/latest/jose/jwe.html
728x90