[oauth] id_token 발급 및 OIDC Discovery 문서 - #438
Conversation
SP가 표준 OIDC 클라이언트 라이브러리(Spring Security oauth2Login, next-auth 등)를 그대로 쓸 수 있게 한다. 기존에는 사용자를 식별하려면 /userinfo를 추가 호출해야 해서 팀마다 수동 연동 코드가 필요했다. - openid scope 지원. 권한이 아니라 "id_token을 함께 달라"는 프로토콜 지시자라 tb_oauth_scope 조회와 client 등록 scope 검사에서 제외한다. 섞인 채로 조회하면 권한 데이터 오류로 500이 난다. - nonce 파라미터를 authorize에서 받아 code에 실어 id_token까지 전달한다. - GET /.well-known/openid-configuration 추가. 지원 목록은 GrantType과 PkceChallengeMethod에서 끌어와, 구현이 바뀌었는데 문서만 남는 상황을 막는다. id_token의 sub는 account.id다. OIDC는 sub가 영구적이고 재사용되지 않는 값일 것을 요구하는데 email은 변경될 수 있어, 바뀌는 순간 SP가 같은 사람을 다른 사용자로 인식한다. access token의 sub는 기존 /userinfo 소비자와의 호환을 위해 email을 유지하므로, 두 토큰의 sub는 서로 다르다.
There was a problem hiding this comment.
-
Overview:
OAuth 인증 서버에 OIDCid_token발급,openidscope 처리,nonce전달, 그리고GET /.well-known/openid-configurationdiscovery 엔드포인트를 추가합니다. -
Intent:
표준 OIDC 클라이언트 라이브러리 연동을 지원하기 위해id_token을 발급하고, SP가 issuer만 알면 엔드포인트와 지원 기능을 자동 발견할 수 있도록 OIDC Discovery 문서를 제공합니다. -
Risk:
위험도: 중간.
집중 확인 대상:id_token의sub가account.id이고 access token의sub는 email로 유지되는 불일치가 기존/향후 SP 연동에 미치는 영향openidscope가 권한이 아닌 프로토콜 지시자로 처리되며, DB scope 조회와 응답 scope 포맷에서 올바르게 분리되는지nonce가 authorize → code → id_token까지 정합적으로 전달되고, 누락/재사용 시 문제가 없는지- Discovery 문서의 issuer/endpoint/userinfo URL/지원 목록이 실제 구현 및 환경 설정과 일치하는지
- 새 환경변수(
OAUTH_USERINFO_URL) 누락 시 동작 및 raw JSON 응답 처리가 의도대로 되는지
0 inline comment(s)
기존에는 OIDC의 "영구 식별자" 요구를 근거로 account.id를 넣었으나, 이 시스템의 계정 email은 학교 계정에 묶여 변경되지 않으므로 그 조건을 이미 만족한다. 바뀌지 않는 값을 두고 별도 식별자를 쓸 이유가 없다. 또한 access token과 /userinfo(JwtProvider가 claims.subject를 email로 읽는다)가 모두 email을 식별자로 쓰고 있어, id_token만 account.id를 쓰면 세 곳의 sub가 어긋나 SP 연동에서 혼란을 만든다. id_token과 access token의 sub가 같은 값인지 확인하는 테스트를 추가했다.
|
개요
SSO 로드맵 우선순위 3(
id_token+openidscope)과 우선순위 4(OIDC Discovery) 를 함께 다룹니다. 로드맵이 "묶어서 하나의 OIDC 준수 PR로"를 권장한 항목입니다.본문
왜 필요한가
현재 발급하는 JWT는 access token(인가용)뿐이라, SP가 "이 사용자가 누구인지" 알려면
/userinfo를 추가 호출해야 합니다. 동작에는 문제없지만 SP가 표준 OIDC 클라이언트 라이브러리(Spring Securityoauth2Login(), next-auth 등)를 쓰려면id_token이 필요하고, 없으면 각 팀이 수동 연동 코드를 작성해야 합니다.논의했던
sub값 — email로 결정로드맵에서 팀 논의가 필요하다고 표시된 항목입니다.
id_token.sub에는 email을 넣습니다.처음에는 OIDC의 "영구적이고 고유한 식별자" 요구를 근거로
account.id를 넣었지만, 이 시스템의 계정 email은 학교 계정에 묶여 변경되지 않으므로 그 조건을 이미 만족합니다. 바뀌지 않는 값을 두고 별도 식별자를 쓸 이유가 없었습니다.일관성 쪽 근거가 더 큽니다. access token의
sub도,/userinfo(datagsm-oauth-userinfo의JwtProvider가claims.subject를 email로 읽습니다)도 email을 식별자로 씁니다. id_token만account.id를 쓰면 세 곳의sub가 어긋나 SP 연동에서 "어느 토큰의 sub인지"를 매번 따져야 합니다.id_token과 access token의sub가 실제로 같은 값인지 확인하는 테스트를 넣어 두 값이 갈라지지 않도록 고정했습니다.변경 내용
1.
openidscopeopenid는 권한이 아니라 "id_token을 함께 달라"는 프로토콜 지시자입니다.applicationId:scopeName형식이 아니고tb_oauth_scope에도 없어서, client 등록 scope 검사와 DB 조회 양쪽에서 제외했습니다. 섞인 채로 조회하면 "권한 데이터가 잘못되었습니다" 500이 납니다.2.
nonce지원authorize에서 받아 code에 실어
id_token클레임까지 전달합니다 (OIDC replay 방지 필수 항목).3.
GET /.well-known/openid-configuration지원 목록을 손으로 적지 않고
GrantType,PkceChallengeMethodenum에서 끌어옵니다. 그러지 않으면 구현이 바뀌었는데 문서만 남아 SP가 지원하지 않는 값을 쓰게 됩니다.sdk.response.not-wrapping-urls에 경로를 추가해CommonApiResponse래핑 없이 raw JSON이 나가도록 했습니다.검증
ktlintCheck build통과openid를 DB scope 조회에서 제외하지 않음 → 4건 실패id_token미발급 → 2건 실패sub에 email이 아닌 다른 값 사용 → 2건 실패nonce클레임 누락 → 1건 실패새 환경변수
Discovery 문서의
userinfo_endpoint에 쓰입니다. UserInfo는 별도 모듈(datagsm-oauth-userinfo)의 다른 호스트라issuer_url에서 유도할 수 없습니다.