LabHub

기업 인증 연동 · SSO 연동 실전 · 실습

OIDC 인가 코드 흐름을 손으로 재현하기

LabHub 에서 이어서 보기

목표

실습용 OIDC 제공자를 상대로 인가 코드 흐름을 직접 손으로 수행하고,
ID 토큰을 디코드·서명 검증하고, 검증 체크리스트를 작성할 수 있게 됩니다.

왜 중요한가

OIDC 를 라이브러리로만 써 본 사람은 장애가 났을 때 어디를 봐야 할지 모릅니다.
redirect_uri 불일치, state 미검증, nonce 누락, 만료된 코드 재사용 —
전부 흐름을 눈으로 본 적이 있어야 감이 옵니다.
특히 ID 토큰은 base64 라 누구나 디코딩할 수 있다는 사실을 손으로 확인하는 것이
중요합니다. 페이로드를 고쳐도 서명 검증을 안 하면 그대로 통과한다는 것을
직접 재현해 보면, 왜 alg 를 고정해야 하는지가 몸으로 남습니다.

단계

1. 실습용 IdP 를 기동합니다.
python3 /opt/lab/fixtures/auth/oidc/idp.py 9000 (백그라운드)
discovery 문서를 받아 /root/oidc/discovery.json 에 저장합니다.
(http://127.0.0.1:9000/.well-known/openid-configuration)
issuer, authorization_endpoint, token_endpoint, jwks_uri 가 있어야 합니다.
2. /root/oidc/auth-url.txt 에 authorization URL 한 줄을 적습니다.
필수 파라미터: response_type=code, client_id=labhub-web,
redirect_uri=http://127.0.0.1:9100/callback,
scope=openid profile email, state=<16자 이상>, nonce=<16자 이상>.
3. 그 URL 을 리다이렉트를 따라가지 않고 호출해 응답의 Location 헤더를
/root/oidc/callback.txt 에 저장하고, 거기서 code 값만 뽑아
/root/oidc/code.txt 에 저장합니다.
Location 의 state 는 2단계에서 보낸 값과 같아야 합니다.
4. 토큰 엔드포인트로 코드를 교환해 응답 JSON 전체를
/root/oidc/token.json 에 저장합니다.
client_id=labhub-web, client_secret=labhub-secret 을 함께 보냅니다.
access_token, id_token, token_type 이 있어야 하고 token_typeBearer 입니다.
5. id_token페이로드를 디코드해 /root/oidc/claims.json 에 저장합니다.
iss, aud, sub, exp, nonce 가 있어야 하고,
audlabhub-web, nonce 는 2단계에서 보낸 값과 같아야 합니다.
6. /root/oidc/verify.sh 를 만듭니다. 인자 두 개(ID토큰 공개키PEM)를 받아
서명이 유효하면 종료코드 0, 아니면 0 이 아닌 값으로 끝냅니다.
공개키는 /opt/lab/fixtures/auth/oidc/idp-public.pem 에 있습니다.
7. access_token 으로 userinfo 엔드포인트를 호출해
/root/oidc/userinfo.json 에 저장합니다.
sub 값이 5단계 claims.jsonsub 와 같아야 합니다.
8. /root/oidc/checklist.csv 를 만듭니다. 첫 줄은 item,risk.
서명, iss, aud, exp, nonce, alg 여섯 항목item 에 있어야 하고,
risk 에는 그 항목을 검증하지 않으면 가능한 공격/사고를 10자 이상으로 적습니다.

참고

단계 8개

  1. IdP 기동과 discovery 문서
  2. authorization URL 조립
  3. 인가 코드 수신
  4. 토큰 교환
  5. ID 토큰 페이로드 디코드
  6. 서명 검증 스크립트
  7. userinfo 호출
  8. ID 토큰 검증 체크리스트