Skip to content

ReSSO v0.9.68

Choose a tag to compare

@hkjang hkjang released this 02 Sep 22:05
· 44 commits to main since this release

RP-Initiated Logout이 RP가 실제로 들고 있는 id_token_hint를 거절하고 있었습니다. hint를 접근용 토큰과 같은 경로(Verify)로 검증해서 만료를 함께 봤는데, 사람이 로그아웃을 누르는 시점에 RP가 저장해둔 ID Token은 보통 이미 만료된 상태입니다 — 기본 Access Token TTL이 5분입니다. 즉 평범한 경우가 거절되고 있었습니다.

수정

  • 거절이 거절로 보이지 않았습니다. hint가 통과하지 못하면 client가 nil로 남고, 그러면 post_logout_redirect_uri말없이 버려집니다. 세션은 끝나고 쿠키도 지워진 채, 브라우저는 RP가 지정한 주소가 아니라 이 서비스의 /login?logged_out=1에 남습니다. RP 입장에서는 사람이 그냥 돌아오지 않고, 응답에는 무시된 파라미터의 이름조차 없습니다.
  • 만료를 보지 않는 이유는 이미 이 저장소에 적혀 있었습니다. 인가 엔드포인트의 같은 파라미터를 읽는 SubjectFromIDTokenHint에 그대로 쓰여 있습니다 — hint는 토큰이 만료됐기 때문에 제시되는 것입니다. RP-Initiated Logout 1.0 §4도 OP에게 같은 것을 요구합니다. 로그아웃만 그것을 따르지 않고 있었습니다.
  • IDTokenHint로 읽습니다. hint를 믿을 만하게 만드는 검사는 그대로 남습니다 — 우리 서명, 우리 issuer. 빠지는 것은 이 파라미터가 존재하는 이유인 그 경우를 거절하던 검사 하나뿐입니다.
  • 느슨해지는 것은 없습니다. 리다이렉트 대상은 여전히 Client에 등록된 목록과 대조하므로 open redirect가 되지 않고, 꺼진 Client는 여전히 거절됩니다.
  • 같은 함수가 반대쪽은 조입니다. Access Token은 옆에서 함께 발급된 ID Token과 issuer·azp·sub가 같아서 그대로 hint로 통과하고 있었습니다. ID Token만이 ID Token이므로 typ을 확인하고, 이 검사는 SubjectFromIDTokenHint를 통해 인가 엔드포인트에도 적용됩니다.
  • 테스트가 양쪽을 모두 덮고, 아무것도 받지 않는 서비스 위에서는 아무것도 증명하지 않겠다고 거부합니다 — 만료되지 않은 hint가 먼저 받아들여져야 하고, 아니면 그 자리에서 실패합니다. 만료된 hint는 기다리지 않고 Realm의 키로 직접 서명했습니다. Realm의 Access Token TTL 하한이 60초이기 때문입니다.

Upgrade notes

동작이 달라집니다: /realms/{realm}/protocol/openid-connect/logout만료된 id_token_hint를 받아들여 post_logout_redirect_uri로 돌려보냅니다(그 주소가 Client에 등록되어 있을 때만입니다). 반대로 Access Token을 id_token_hint로 보내던 곳은 이제 거절되므로, 그렇게 붙여둔 RP가 있다면 ID Token을 보내도록 고치셔야 합니다 — 스펙이 요구하는 값입니다. 저장되는 데이터는 바뀌지 않고 되돌릴 때 이전 이미지도 그대로 동작합니다.


Docker image: resso:v0.9.68

Archive: resso-v0.9.68.tar.gz

SHA-256: c5e92044cc45b21c1141474b921678044d7c6ae2ccb9d070a528ecaaece1f5c2