From e9917c72513d3b2a49e86314a2c1fdfa9ec6bc91 Mon Sep 17 00:00:00 2001 From: Nick Mastoris Date: Thu, 9 May 2024 06:03:53 +0000 Subject: [PATCH 1/6] fix support for resource indicator(auth_code) --- src/idpyoidc/server/authz/__init__.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/idpyoidc/server/authz/__init__.py b/src/idpyoidc/server/authz/__init__.py index 7752e531..bcb4929d 100755 --- a/src/idpyoidc/server/authz/__init__.py +++ b/src/idpyoidc/server/authz/__init__.py @@ -76,9 +76,9 @@ def __call__( else: setattr(grant, key, val) - if resources is None: + if resources is None and grant.resources is None: grant.resources = [_client_id] - else: + elif resources is not None: grant.resources = resources # Scope handling. If allowed scopes are defined for the client filter using that From 404164cae8404146c46ee84e3a14ae5d6525d428 Mon Sep 17 00:00:00 2001 From: Nick Mastoris Date: Thu, 9 May 2024 06:34:25 +0000 Subject: [PATCH 2/6] minor fix --- src/idpyoidc/server/authz/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/idpyoidc/server/authz/__init__.py b/src/idpyoidc/server/authz/__init__.py index bcb4929d..5dfb5991 100755 --- a/src/idpyoidc/server/authz/__init__.py +++ b/src/idpyoidc/server/authz/__init__.py @@ -76,7 +76,7 @@ def __call__( else: setattr(grant, key, val) - if resources is None and grant.resources is None: + if resources is None and (grant.resources is None or len(grant.resources) == 0): grant.resources = [_client_id] elif resources is not None: grant.resources = resources From aae80eb951415740aa82ca006469ce62ea47f988 Mon Sep 17 00:00:00 2001 From: Nick Mastoris Date: Mon, 20 May 2024 05:31:27 +0000 Subject: [PATCH 3/6] add resource indicators support for client credentials --- src/idpyoidc/message/oauth2/__init__.py | 1 + .../oauth2/token_helper/client_credentials.py | 51 +++++++++++++++++++ 2 files changed, 52 insertions(+) diff --git a/src/idpyoidc/message/oauth2/__init__.py b/src/idpyoidc/message/oauth2/__init__.py index 788fe8c5..066b33ef 100644 --- a/src/idpyoidc/message/oauth2/__init__.py +++ b/src/idpyoidc/message/oauth2/__init__.py @@ -303,6 +303,7 @@ class CCAccessTokenRequest(Message): "client_secret": SINGLE_OPTIONAL_STRING, "grant_type": SINGLE_REQUIRED_STRING, "scope": OPTIONAL_LIST_OF_SP_SEP_STRINGS, + "resource": OPTIONAL_LIST_OF_STRINGS, } def verify(self, **kwargs): diff --git a/src/idpyoidc/server/oauth2/token_helper/client_credentials.py b/src/idpyoidc/server/oauth2/token_helper/client_credentials.py index fa3db7cd..874517ab 100755 --- a/src/idpyoidc/server/oauth2/token_helper/client_credentials.py +++ b/src/idpyoidc/server/oauth2/token_helper/client_credentials.py @@ -3,11 +3,13 @@ from typing import Union from idpyoidc.message import Message +from idpyoidc.message.oauth2 import TokenErrorResponse from idpyoidc.message.oauth2 import CCAccessTokenRequest from idpyoidc.time_util import utc_time_sans_frac from idpyoidc.util import sanitize from . import TokenEndpointHelper +from . import validate_resource_indicators_policy logger = logging.getLogger(__name__) @@ -45,11 +47,38 @@ def process_request(self, req: Union[Message, dict], **kwargs): branch_id = _mngr.add_grant(["client_credentials", client_id]) _session_info = _mngr.get_session_info(branch_id) + + ## LIONICK CHANGE START + _cinfo = _context.cdb.get(client_id) + + if "resource_indicators" in _cinfo and "client_credentials" in _cinfo["resource_indicators"]: + resource_indicators_config = _cinfo["resource_indicators"]["client_credentials"] + else: + resource_indicators_config = self.endpoint.kwargs.get("resource_indicators", None) + + if resource_indicators_config is not None: + if "policy" not in resource_indicators_config: + policy = {"policy": {"function": validate_resource_indicators_policy}} + resource_indicators_config.update(policy) + + req = self._enforce_resource_indicators_policy(req, resource_indicators_config) + + if isinstance(req, TokenErrorResponse): + return req + + ## LIONICK CHANGE END _grant = _session_info["grant"] token_type = "Bearer" _allowed = _context.cdb[client_id].get("allowed_scopes", []) + ## LIONICK CHANGE START + resources = req.get("resource", None) + if resources: + token_args = {"resources": resources} + else: + token_args = None + ## LIONICK CHANGE END access_token = self._mint_token( token_class="access_token", grant=_grant, @@ -58,6 +87,7 @@ def process_request(self, req: Union[Message, dict], **kwargs): based_on=None, scope=_allowed, token_type=token_type, + token_args=token_args, ) _resp = { @@ -77,3 +107,24 @@ def post_parse_request( request = CCAccessTokenRequest(**request.to_dict()) logger.debug("%s: %s" % (request.__class__.__name__, sanitize(request))) return request + + def _enforce_resource_indicators_policy(self, request, config): + _context = self.endpoint.upstream_get("context") + + policy = config["policy"] + function = policy["function"] + kwargs = policy.get("kwargs", {}) + + if isinstance(function, str): + try: + fn = importer(function) + except Exception: + raise ImproperlyConfigured(f"Error importing {function} policy function") + else: + fn = function + try: + return fn(request, context=_context, **kwargs) + except Exception as e: + logger.error(f"Error while executing the {fn} policy function: {e}") + return self.error_cls(error="server_error", error_description="Internal server error") + From 4dc8ee6df271d3993aedbad772f98e5d64a944be Mon Sep 17 00:00:00 2001 From: Nick Mastoris Date: Mon, 20 May 2024 05:33:36 +0000 Subject: [PATCH 4/6] remove comments --- .../server/oauth2/token_helper/client_credentials.py | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/idpyoidc/server/oauth2/token_helper/client_credentials.py b/src/idpyoidc/server/oauth2/token_helper/client_credentials.py index 874517ab..c1a919dc 100755 --- a/src/idpyoidc/server/oauth2/token_helper/client_credentials.py +++ b/src/idpyoidc/server/oauth2/token_helper/client_credentials.py @@ -24,7 +24,6 @@ def process_request(self, req: Union[Message, dict], **kwargs): logger.debug("Client credentials flow") # verify the client and the user - client_id = req["client_id"] _authenticated = req.get("authenticated", False) if not _authenticated: @@ -47,8 +46,6 @@ def process_request(self, req: Union[Message, dict], **kwargs): branch_id = _mngr.add_grant(["client_credentials", client_id]) _session_info = _mngr.get_session_info(branch_id) - - ## LIONICK CHANGE START _cinfo = _context.cdb.get(client_id) if "resource_indicators" in _cinfo and "client_credentials" in _cinfo["resource_indicators"]: @@ -66,19 +63,16 @@ def process_request(self, req: Union[Message, dict], **kwargs): if isinstance(req, TokenErrorResponse): return req - ## LIONICK CHANGE END _grant = _session_info["grant"] token_type = "Bearer" _allowed = _context.cdb[client_id].get("allowed_scopes", []) - ## LIONICK CHANGE START resources = req.get("resource", None) if resources: token_args = {"resources": resources} else: token_args = None - ## LIONICK CHANGE END access_token = self._mint_token( token_class="access_token", grant=_grant, From b1cbba77abfdfbf36d4b2022264231ac3a2dc75c Mon Sep 17 00:00:00 2001 From: Nick Mastoris Date: Mon, 20 May 2024 05:47:07 +0000 Subject: [PATCH 5/6] add missing import --- src/idpyoidc/server/oauth2/token_helper/client_credentials.py | 1 + 1 file changed, 1 insertion(+) diff --git a/src/idpyoidc/server/oauth2/token_helper/client_credentials.py b/src/idpyoidc/server/oauth2/token_helper/client_credentials.py index c1a919dc..dcae0d0b 100755 --- a/src/idpyoidc/server/oauth2/token_helper/client_credentials.py +++ b/src/idpyoidc/server/oauth2/token_helper/client_credentials.py @@ -6,6 +6,7 @@ from idpyoidc.message.oauth2 import TokenErrorResponse from idpyoidc.message.oauth2 import CCAccessTokenRequest from idpyoidc.time_util import utc_time_sans_frac +from idpyoidc.util import importer from idpyoidc.util import sanitize from . import TokenEndpointHelper From 52baeb3ffa7332219e081fb6d745ee4652cbe997 Mon Sep 17 00:00:00 2001 From: Nick Mastoris Date: Mon, 20 May 2024 05:51:18 +0000 Subject: [PATCH 6/6] add missing import --- src/idpyoidc/server/oauth2/token_helper/client_credentials.py | 1 + 1 file changed, 1 insertion(+) diff --git a/src/idpyoidc/server/oauth2/token_helper/client_credentials.py b/src/idpyoidc/server/oauth2/token_helper/client_credentials.py index dcae0d0b..c23e327c 100755 --- a/src/idpyoidc/server/oauth2/token_helper/client_credentials.py +++ b/src/idpyoidc/server/oauth2/token_helper/client_credentials.py @@ -2,6 +2,7 @@ from typing import Optional from typing import Union +from idpyoidc.exception import ImproperlyConfigured from idpyoidc.message import Message from idpyoidc.message.oauth2 import TokenErrorResponse from idpyoidc.message.oauth2 import CCAccessTokenRequest