From e631fc3ed8f6b5834740b35126926489db722217 Mon Sep 17 00:00:00 2001 From: Kostis Triantafyllakis Date: Wed, 26 Jul 2023 19:39:55 +0300 Subject: [PATCH 1/3] Unbind authentication event lifetime from userinfo response Signed-off-by: Kostis Triantafyllakis --- src/idpyoidc/server/oidc/userinfo.py | 40 +++++++--------------------- 1 file changed, 10 insertions(+), 30 deletions(-) diff --git a/src/idpyoidc/server/oidc/userinfo.py b/src/idpyoidc/server/oidc/userinfo.py index 32d77506..5bf3acaa 100755 --- a/src/idpyoidc/server/oidc/userinfo.py +++ b/src/idpyoidc/server/oidc/userinfo.py @@ -64,7 +64,6 @@ def do_response( client_id: Optional[str] = "", **kwargs, ) -> dict: - if "error" in kwargs and kwargs["error"]: return Endpoint.do_response(self, response_args, request, **kwargs) @@ -135,35 +134,16 @@ def process_request(self, request=None, **kwargs): if token.is_active() is False: return self.error_cls(error="invalid_token", error_description="Invalid Token") - allowed = True - _auth_event = _grant.authentication_event - # if the authentication is still active or offline_access is granted. - if not _auth_event["valid_until"] >= utc_time_sans_frac(): - logger.debug( - "authentication not valid: {} > {}".format( - datetime.fromtimestamp(_auth_event["valid_until"]), - datetime.fromtimestamp(utc_time_sans_frac()), - ) - ) - allowed = False - - # This has to be made more finegrained. - # if "offline_access" in session["authn_req"]["scope"]: - # pass - _cntxt = self.upstream_get("context") - if allowed: - _claims_restriction = _cntxt.claims_interface.get_claims( - _session_info["branch_id"], scopes=token.scope, claims_release_point="userinfo" - ) - info = _cntxt.claims_interface.get_user_claims( - _session_info["user_id"], - claims_restriction=_claims_restriction, - client_id=_session_info["client_id"] - ) - info["sub"] = _grant.sub - if _grant.add_acr_value("userinfo"): - info["acr"] = _grant.authentication_event["authn_info"] + _claims_restriction = _cntxt.claims_interface.get_claims( + _session_info["branch_id"], scopes=token.scope, claims_release_point="userinfo" + ) + info = _cntxt.claims_interface.get_user_claims( + _session_info["user_id"], claims_restriction=_claims_restriction + ) + info["sub"] = _grant.sub + if _grant.add_acr_value("userinfo"): + info["acr"] = _grant.authentication_event["authn_info"] extra_claims = kwargs.get("extra_claims") if extra_claims: @@ -213,7 +193,7 @@ def parse_request(self, request, http_info=None, **kwargs): def _enforce_policy(self, request, response_info, token, config): policy = config["policy"] callable = policy["function"] - kwargs = policy.get("kwargs", {}) + kwargs = policy.get("kwargs") or {} if isinstance(callable, str): try: From cc1d61ff454275ff0e921aae7ce996fd07978613 Mon Sep 17 00:00:00 2001 From: Ivan Kanakarakis Date: Mon, 15 Jul 2024 12:01:45 +0300 Subject: [PATCH 2/3] Ensure the access_token contains the openid scope Signed-off-by: Ivan Kanakarakis --- src/idpyoidc/server/oidc/userinfo.py | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/src/idpyoidc/server/oidc/userinfo.py b/src/idpyoidc/server/oidc/userinfo.py index 5bf3acaa..1a9c325a 100755 --- a/src/idpyoidc/server/oidc/userinfo.py +++ b/src/idpyoidc/server/oidc/userinfo.py @@ -125,18 +125,27 @@ def process_request(self, request=None, **kwargs): return self.error_cls(error="invalid_token", error_description="Invalid Token") _grant = _session_info["grant"] - token = _grant.get_token(request["access_token"]) - # should be an access token - if token and token.token_class != "access_token": + access_token = _grant.get_token(request["access_token"]) + + # there must be a token + if not access_token: + return self.error_cls(error="invalid_token", error_description="Invalid Token") + + # the token must be an access_token + if access_token.token_class != "access_token": return self.error_cls(error="invalid_token", error_description="Wrong type of token") - # And it should be valid - if token.is_active() is False: + # the access_token must be valid + if access_token.is_active() is False: + return self.error_cls(error="invalid_token", error_description="Invalid Token") + + # the access_token must contain the openid scope + if "openid" not in access_token.scope: return self.error_cls(error="invalid_token", error_description="Invalid Token") _cntxt = self.upstream_get("context") _claims_restriction = _cntxt.claims_interface.get_claims( - _session_info["branch_id"], scopes=token.scope, claims_release_point="userinfo" + _session_info["branch_id"], scopes=access_token.scope, claims_release_point="userinfo" ) info = _cntxt.claims_interface.get_user_claims( _session_info["user_id"], claims_restriction=_claims_restriction @@ -153,7 +162,7 @@ def process_request(self, request=None, **kwargs): self.config["policy"] = _cntxt.cdb[request["client_id"]]["userinfo"]["policy"] if "policy" in self.config: - info = self._enforce_policy(request, info, token, self.config) + info = self._enforce_policy(request, info, access_token, self.config) return {"response_args": info, "client_id": _session_info["client_id"]} From d74a312586a9464ff3bdd8bb8d93ee28dc2c4c50 Mon Sep 17 00:00:00 2001 From: Nick Mastoris Date: Thu, 7 Nov 2024 08:48:37 +0000 Subject: [PATCH 3/3] add missing parameter --- src/idpyoidc/server/oidc/userinfo.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/idpyoidc/server/oidc/userinfo.py b/src/idpyoidc/server/oidc/userinfo.py index 1a9c325a..281b669d 100755 --- a/src/idpyoidc/server/oidc/userinfo.py +++ b/src/idpyoidc/server/oidc/userinfo.py @@ -148,7 +148,8 @@ def process_request(self, request=None, **kwargs): _session_info["branch_id"], scopes=access_token.scope, claims_release_point="userinfo" ) info = _cntxt.claims_interface.get_user_claims( - _session_info["user_id"], claims_restriction=_claims_restriction + _session_info["user_id"], claims_restriction=_claims_restriction, + client_id=_session_info["client_id"] ) info["sub"] = _grant.sub if _grant.add_acr_value("userinfo"):