Skip to content

Commit f4a483d

Browse files
authored
Merge pull request #829 from infohash/bugfix/end-session-logout-missing-id-token-hint
Fixed RP-Initiated Logout To Accept id_token_hint
2 parents e8e5ba3 + ef8afa2 commit f4a483d

4 files changed

Lines changed: 47 additions & 13 deletions

File tree

CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,17 @@ The format is based on the [KeepAChangeLog] project.
1010
### Changed
1111
- [#827] Added support for python 3.11
1212

13+
### Fixed
14+
- [#826], [#829] Fixed RP-Initiated Logout To Accept id_token_hint
15+
1316
## Removed
1417

1518
- [#820] Removed Client.grant_from_state method.
1619

1720
[#820]: https://github.com/OpenIDC/pyoidc/pull/820
1821
[#827]: https://github.com/OpenIDC/pyoidc/issues/827
22+
[#826]: https://github.com/OpenIDC/pyoidc/issues/826
23+
[#829]: https://github.com/OpenIDC/pyoidc/pull/829
1924

2025
## 1.4.0 [2022-05-23]
2126

mypy.ini

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
[mypy]
22
check_untyped_defs = True
3+
no_implicit_optional = False
34

45
[mypy-jwkest.*]
56
ignore_missing_imports = True

src/oic/oic/__init__.py

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -647,7 +647,12 @@ def construct_CheckIDRequest(
647647
)
648648

649649
def construct_EndSessionRequest(
650-
self, request=None, request_args=None, extra_args=None, **kwargs
650+
self,
651+
request=None,
652+
request_args=None,
653+
extra_args=None,
654+
prop="id_token_hint",
655+
**kwargs,
651656
):
652657

653658
if request is None:
@@ -658,7 +663,9 @@ def construct_EndSessionRequest(
658663
if "state" in request_args and "state" not in kwargs:
659664
kwargs["state"] = request_args["state"]
660665

661-
return self._id_token_based(request, request_args, extra_args, **kwargs)
666+
return self._id_token_based(
667+
request, request_args, extra_args, prop=prop, **kwargs
668+
)
662669

663670
def do_authorization_request(
664671
self,
@@ -824,6 +831,7 @@ def do_end_session_request(
824831
request_args=None,
825832
extra_args=None,
826833
http_args=None,
834+
prop="id_token_hint",
827835
):
828836
request = self.message_factory.get_request_type("endsession_endpoint")
829837
response_cls = self.message_factory.get_response_type("endsession_endpoint")
@@ -834,6 +842,7 @@ def do_end_session_request(
834842
extra_args=extra_args,
835843
scope=scope,
836844
state=state,
845+
prop=prop,
837846
)
838847

839848
if http_args is None:

tests/test_oic.py

Lines changed: 30 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -415,9 +415,10 @@ def test_do_end_session_request(self):
415415
alg = "RS256"
416416
ktyp = alg2keytype(alg)
417417
_sign_key = self.client.keyjar.get_signing_key(ktyp)
418+
id_token_jwt = IDTOKEN.to_jwt(key=_sign_key, algorithm=alg)
418419
args = {
419-
"id_token": IDTOKEN.to_jwt(key=_sign_key, algorithm=alg),
420-
"redirect_url": "http://example.com/end",
420+
"id_token_hint": id_token_jwt,
421+
"post_logout_redirect_uri": "http://example.com/end",
421422
}
422423

423424
with responses.RequestsMock() as rsps:
@@ -427,10 +428,10 @@ def test_do_end_session_request(self):
427428
status=302,
428429
headers={"location": ""},
429430
)
430-
resp = self.client.do_end_session_request(request_args=args, state="state1")
431+
resp = self.client.do_end_session_request(request_args=args)
431432
parsed = parse_qs(urlparse(resp.request.url).query)
432-
assert parsed["redirect_url"] == ["http://example.com/end"]
433-
assert parsed["id_token"] is not None
433+
assert parsed["post_logout_redirect_uri"] == ["http://example.com/end"]
434+
assert parsed["id_token_hint"] == [id_token_jwt]
434435

435436
def test_do_registration_request(self):
436437
self.client.registration_endpoint = ( # type: ignore
@@ -681,9 +682,9 @@ def test_construct_EndSessionRequest_kwargs_state(self):
681682
self.client.grant["foo"].tokens.append(Token(resp))
682683

683684
# state only in kwargs
684-
args = {"redirect_url": "http://example.com/end"}
685+
args = {"post_logout_redirect_uri": "http://example.com/end"}
685686
esr = self.client.construct_EndSessionRequest(state="foo", request_args=args)
686-
assert _eq(esr.keys(), ["id_token", "redirect_url"])
687+
assert _eq(esr.keys(), ["id_token_hint", "post_logout_redirect_uri"])
687688

688689
def test_construct_EndSessionRequest_reqargs_state(self):
689690
self.client.grant["foo"] = Grant()
@@ -708,9 +709,9 @@ def test_construct_EndSessionRequest_reqargs_state(self):
708709
self.client.grant["foo"].tokens.append(Token(resp))
709710

710711
# state only in request_args
711-
args = {"redirect_url": "http://example.com/end", "state": "foo"}
712+
args = {"post_logout_redirect_uri": "http://example.com/end", "state": "foo"}
712713
esr = self.client.construct_EndSessionRequest(request_args=args)
713-
assert _eq(esr.keys(), ["id_token", "state", "redirect_url"])
714+
assert _eq(esr.keys(), ["id_token_hint", "state", "post_logout_redirect_uri"])
714715

715716
def test_construct_EndSessionRequest_kwargs_and_reqargs_state(self):
716717
self.client.grant["foo"] = Grant()
@@ -734,11 +735,29 @@ def test_construct_EndSessionRequest_kwargs_and_reqargs_state(self):
734735
self.client.grant["foo"].tokens.append(Token(resp))
735736

736737
# state both in request_args and kwargs
737-
args = {"redirect_url": "http://example.com/end", "state": "req_args_state"}
738+
args = {
739+
"post_logout_redirect_uri": "http://example.com/end",
740+
"state": "req_args_state",
741+
}
738742
esr = self.client.construct_EndSessionRequest(state="foo", request_args=args)
739-
assert _eq(esr.keys(), ["id_token", "state", "redirect_url"])
743+
assert _eq(esr.keys(), ["id_token_hint", "state", "post_logout_redirect_uri"])
740744
assert esr["state"] == "req_args_state"
741745

746+
def test_construct_EndSessionRequest_with_id_token_hint_and_post_logout_redirect_uri(
747+
self,
748+
):
749+
"""Should construct end session request using id_token_hint and post_logout_redirect_uri"""
750+
self.client.keyjar.add_kb(IDTOKEN["iss"], KC_SYM_S)
751+
_sig_key = self.client.keyjar.get_signing_key("oct", IDTOKEN["iss"])
752+
_signed_jwt = IDTOKEN.to_jwt(_sig_key, algorithm="HS256")
753+
754+
args = {
755+
"post_logout_redirect_uri": "http://example.com/end",
756+
"id_token_hint": _signed_jwt,
757+
}
758+
esr = self.client.construct_EndSessionRequest(request_args=args)
759+
assert _eq(esr.keys(), ["id_token_hint", "post_logout_redirect_uri"])
760+
742761
def test_construct_OpenIDRequest(self):
743762
request_args = {"response_type": "code id_token", "state": "af0ifjsldkj"}
744763

0 commit comments

Comments
 (0)