LabHub

Keycloak 과 기업 인증 · OIDC 토큰과 검증 · 실습

JWT 파싱과 서명·클레임 검증

LabHub 에서 이어서 보기

목표

JWT 를 손으로 뜯어 서명을 검증하고 클레임을 확인하면서, 라이브러리가 대신 해 주던 일이 정확히 무엇인지 이해한다.

왜 중요한가

JWT 검증은 라이브러리 한 줄이라 내부를 모르고 지나치기 쉽습니다. 그런데 그 한 줄에 옵션을 잘못 주면 조용히 뚫립니다. 대표적으로 aud 검사를 켜지 않으면, 같은 인증 서버가 발급한 다른 API 용 토큰이 우리 API 에서 통과합니다. alg 를 검증하지 않으면 none 알고리즘으로 서명 없는 토큰이 통과한 사고가 실제로 있었습니다. 그리고 이 실습에서 마지막에 재는 숫자가 중요합니다 — introspection 은 매 요청 네트워크 왕복이고 로컬 검증은 CPU 연산입니다. 마이크로서비스 열 개가 각각 물어보면 인증 서버가 병목이 되기 때문에, 실무는 액세스 토큰을 5~15분으로 짧게 두고 로컬 검증을 씁니다. 취소 반영 지연을 토큰 수명만큼으로 제한하는 거래입니다.

단계

1. /root/kc/wait.shhttp://127.0.0.1:8080/realms/master 가 200 이 될 때까지 최대 180초 기다린다. /root/kc/ready.txtready_seconds=<정수> 를 적는다.
2. /opt/fixtures/kc/realm-info.env 의 값으로 토큰을 발급받아 /root/kc/token.txt 에 액세스 토큰만 한 줄 저장한다. 점이 2개인 문자열이어야 한다.
3. /root/kc/decode.py 로 헤더를 /root/kc/header.json, 페이로드를 /root/kc/claims.json 에 저장한다. 둘 다 유효한 JSON 이어야 한다.
4. /root/kc/claimcheck.txtiss=<값> aud=<값> sub=<값> exp_in=<남은초> 를 적는다. exp_in 은 0보다 커야 한다.
5. http://127.0.0.1:8080/realms/labhub/protocol/openid-connect/certs 에서 JWKS 를 받아, 헤더의 kid 와 일치하는 키를 /root/kc/jwk.json 에 저장한다. ktyRSA 여야 한다.
6. /root/kc/verify.py 로 서명을 검증하고 /root/kc/verify.outsignature=valid alg=<값> 을 적는다.
7. 페이로드를 변조한 토큰으로 같은 검증을 돌려 /root/kc/tamper.outsignature=invalid 를 적는다.

참고

단계 7개

  1. Keycloak 준비될 때까지 기다리기
  2. 토큰 발급받기
  3. 헤더와 페이로드 디코드하기
  4. 필수 클레임 확인하기
  5. JWKS 에서 서명 키 찾기
  6. 서명 검증하기
  7. 변조 토큰이 거부되는지 확인하기