From 82d6172a86b29785b98747de03cf6e861ddb222d Mon Sep 17 00:00:00 2001 From: Glauco <37829079+rglauco@users.noreply.github.com> Date: Tue, 6 Feb 2024 20:07:33 +0100 Subject: [PATCH 01/10] feat: added get_client_organisation_name method to retrieve the correct RP name --- spid_cie_oidc/provider/views/__init__.py | 75 +++++++++++-------- .../provider/views/authz_request_view.py | 10 ++- .../provider/views/consent_page_view.py | 4 +- 3 files changed, 52 insertions(+), 37 deletions(-) diff --git a/spid_cie_oidc/provider/views/__init__.py b/spid_cie_oidc/provider/views/__init__.py index 8ca9832d..3ef40868 100644 --- a/spid_cie_oidc/provider/views/__init__.py +++ b/spid_cie_oidc/provider/views/__init__.py @@ -32,6 +32,7 @@ OIDCFED_PROVIDER_PROFILES_ACR_4_REFRESH, OIDCFED_PROVIDER_PROFILES_ID_TOKEN_CLAIMS ) + logger = logging.getLogger(__name__) @@ -40,7 +41,7 @@ class OpBase: Baseclass with common methods for OPs """ - def redirect_response_data(self, redirect_uri:str, **kwargs) -> HttpResponseRedirect: + def redirect_response_data(self, redirect_uri: str, **kwargs) -> HttpResponseRedirect: if "?" in redirect_uri: qstring = "&" else: @@ -114,7 +115,7 @@ def validate_authz_request_object(self, req) -> TrustChain: jwks = get_jwks( rp_trust_chain.metadata['openid_relying_party'], - federation_jwks = rp_trust_chain.jwks + federation_jwks=rp_trust_chain.jwks ) jwk = self.find_jwk(header, jwks) if not jwk: @@ -178,7 +179,7 @@ def check_session(self, request) -> OidcSession: ) session_not_after = session.created + timezone.timedelta( - minutes = OIDCFED_PROVIDER_AUTH_CODE_MAX_AGE + minutes=OIDCFED_PROVIDER_AUTH_CODE_MAX_AGE ) if session_not_after < timezone.localtime(): raise ExpiredAuthCode( @@ -199,12 +200,12 @@ def check_client_assertion(self, client_id: str, client_assertion: str) -> bool: _op = self.get_issuer() _op_eid = _op.sub _op_eid_authz_endpoint = [_op.metadata['openid_provider']['authorization_endpoint']] - + try: ClientAssertion(**payload) except Exception as e: raise Exception(f"Client Assertion: json schema validation error: {e}") - + if isinstance(_aud, str): _aud = [_aud] _allowed_auds = _aud + _op_eid_authz_endpoint @@ -250,9 +251,9 @@ def get_jwt_common_data(self): } def get_access_token( - self, iss_sub:str, sub:str, authz: OidcSession, commons:dict + self, iss_sub: str, sub: str, authz: OidcSession, commons: dict ) -> dict: - + access_token = { "iss": iss_sub, "sub": sub, @@ -266,8 +267,8 @@ def get_access_token( return access_token def get_id_token_claims( - self, - authz:OidcSession + self, + authz: OidcSession ) -> dict: _provider_profile = getattr(settings, 'OIDCFED_DEFAULT_PROVIDER_PROFILE', OIDCFED_DEFAULT_PROVIDER_PROFILE) claims = {} @@ -276,21 +277,21 @@ def get_id_token_claims( return claims for claim in ( - authz.authz_request.get( - "claims", {} - ).get("id_token", {}).keys() + authz.authz_request.get( + "claims", {} + ).get("id_token", {}).keys() ): if claim in allowed_id_token_claims and authz.user.attributes.get(claim, None): claims[claim] = authz.user.attributes[claim] return claims def get_id_token( - self, - iss_sub:str, - sub:str, - authz:OidcSession, - jwt_at:str, - commons:dict + self, + iss_sub: str, + sub: str, + authz: OidcSession, + jwt_at: str, + commons: dict ) -> dict: id_token = { @@ -312,19 +313,19 @@ def get_id_token( def get_refresh_token( self, - iss_sub:str, - sub:str, - authz:OidcSession, - jwt_at:str, - commons:dict + iss_sub: str, + sub: str, + authz: OidcSession, + jwt_at: str, + commons: dict ) -> dict: # refresh token is scope offline_access and prompt == consent refresh_acrs = OIDCFED_PROVIDER_PROFILES_ACR_4_REFRESH[OIDCFED_DEFAULT_PROVIDER_PROFILE] acrs = authz.authz_request.get('acr_values', []) if ( - "offline_access" in authz.authz_request['scope'] and - 'consent' in authz.authz_request['prompt'] and - set(refresh_acrs).intersection(set(acrs)) + "offline_access" in authz.authz_request['scope'] and + 'consent' in authz.authz_request['prompt'] and + set(refresh_acrs).intersection(set(acrs)) ): refresh_token = { "sub": sub, @@ -337,8 +338,8 @@ def get_refresh_token( refresh_token.update(commons) return refresh_token - def get_iss_token_data(self, session : OidcSession, issuer: FederationEntityConfiguration): - _sub = session.pairwised_sub(provider_id = issuer.sub) + def get_iss_token_data(self, session: OidcSession, issuer: FederationEntityConfiguration): + _sub = session.pairwised_sub(provider_id=issuer.sub) iss_sub = issuer.sub commons = self.get_jwt_common_data() jwk = issuer.jwks_core[0] @@ -363,7 +364,7 @@ def get_iss_token_data(self, session : OidcSession, issuer: FederationEntityConf def get_expires_in(self, iat: int, exp: int): return timezone.timedelta( - seconds = exp - iat + seconds=exp - iat ).seconds def attributes_names_to_release(self, request, session: OidcSession) -> dict: @@ -391,6 +392,18 @@ def attributes_names_to_release(self, request, session: OidcSession) -> dict: for i in filtered_user_claims.keys() ] return dict( - i18n_user_claims = i18n_user_claims, - filtered_user_claims = filtered_user_claims + i18n_user_claims=i18n_user_claims, + filtered_user_claims=filtered_user_claims ) + + def get_client_organisation_name(self, tc): + fed_metadata = tc.metadata.get("federation_entity", {}) + name = fed_metadata.get("organization_name", "") + if not name: + op_metadata = tc.metadata.get("openid_relying_party", {}) + name = op_metadata.get("organization_name", "") + if not name: + name = op_metadata.get("client_name", "") + if not name: + name = op_metadata.get("client_id", "") + return name diff --git a/spid_cie_oidc/provider/views/authz_request_view.py b/spid_cie_oidc/provider/views/authz_request_view.py index 415b738f..b59d4cf2 100644 --- a/spid_cie_oidc/provider/views/authz_request_view.py +++ b/spid_cie_oidc/provider/views/authz_request_view.py @@ -198,10 +198,14 @@ def get(self, request, *args, **kwargs): # stores the authz request in a hidden field in the form form = self.get_login_form()() + + # context = { + # "client_organization_name": tc.metadata.get( + # "client_name", self.payload["client_id"] + # ), + context = { - "client_organization_name": tc.metadata.get( - "client_name", self.payload["client_id"] - ), + "client_organization_name": self.get_client_organisation_name(tc), "hidden_form": AuthzHiddenForm(dict(authz_request_object=req)), "form": form, "redirect_uri": self.payload["redirect_uri"], diff --git a/spid_cie_oidc/provider/views/consent_page_view.py b/spid_cie_oidc/provider/views/consent_page_view.py index 14fb0b26..56ffd843 100644 --- a/spid_cie_oidc/provider/views/consent_page_view.py +++ b/spid_cie_oidc/provider/views/consent_page_view.py @@ -56,9 +56,7 @@ def get(self, request, *args, **kwargs): context = { "form": self.get_consent_form()(), "session": session, - "client_organization_name": tc.metadata.get( - "client_name", session.client_id - ), + "client_organization_name": self.get_client_organisation_name(tc), "user_claims": sorted(set(i18n_user_claims),), "redirect_uri": session.authz_request["redirect_uri"], "state": session.authz_request["state"] From 4740ea5bccf81153f15b985d8ac46b995eb24ade Mon Sep 17 00:00:00 2001 From: Glauco <37829079+rglauco@users.noreply.github.com> Date: Tue, 6 Feb 2024 20:16:55 +0100 Subject: [PATCH 02/10] chore: fix CIE organization_name --- examples/provider/dumps/example.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/provider/dumps/example.json b/examples/provider/dumps/example.json index 06242afd..fb0e7e4b 100644 --- a/examples/provider/dumps/example.json +++ b/examples/provider/dumps/example.json @@ -147,7 +147,7 @@ "metadata": { "federation_entity": { "federation_resolve_endpoint": "http://127.0.0.1:8002/oidc/op/resolve", - "organization_name": "SPID OIDC identity provider", + "organization_name": "CIE OIDC identity provider", "homepage_uri": "http://127.0.0.1:8002", "policy_uri": "http://127.0.0.1:8002/oidc/op/en/website/legal-information", "logo_uri": "http://127.0.0.1:8002/static/svg/logo-cie.svg", From 6403674dae07cf5536c82357b459b5cad261b1b6 Mon Sep 17 00:00:00 2001 From: Glauco <37829079+rglauco@users.noreply.github.com> Date: Wed, 7 Feb 2024 07:42:29 +0100 Subject: [PATCH 03/10] fix: updated cryptography rsa import to 42.0.2 --- spid_cie_oidc/entity/jwks.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/spid_cie_oidc/entity/jwks.py b/spid_cie_oidc/entity/jwks.py index 9726d505..b65f844d 100644 --- a/spid_cie_oidc/entity/jwks.py +++ b/spid_cie_oidc/entity/jwks.py @@ -2,7 +2,7 @@ from cryptojwt.jwk.rsa import new_rsa_key from cryptography.hazmat.primitives import serialization from cryptojwt.jwk.rsa import RSAKey - +from cryptography.hazmat.primitives.asymmetric import rsa import cryptography from django.conf import settings @@ -64,9 +64,9 @@ def serialize_rsa_key(rsa_key, kind="public", hash_func="SHA-256"): cryptography.hazmat.backends.openssl.rsa._RSAPrivateKey """ data = {} - if isinstance(rsa_key, cryptography.hazmat.backends.openssl.rsa._RSAPublicKey): + if isinstance(rsa_key, rsa.RSAPublicKey): data = {"pub_key": rsa_key} - elif isinstance(rsa_key, cryptography.hazmat.backends.openssl.rsa._RSAPrivateKey): + elif isinstance(rsa_key, rsa.RSAPrivateKey): data = {"priv_key": rsa_key} elif isinstance(rsa_key, (str, bytes)): # pragma: no cover if kind == "private": From ab823916862cc07558afc3712e008a28a407b4c6 Mon Sep 17 00:00:00 2001 From: Glauco <37829079+rglauco@users.noreply.github.com> Date: Wed, 7 Feb 2024 08:02:04 +0100 Subject: [PATCH 04/10] chore: bump to 1.3.1 --- spid_cie_oidc/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spid_cie_oidc/__init__.py b/spid_cie_oidc/__init__.py index 67bc602a..9c73af26 100644 --- a/spid_cie_oidc/__init__.py +++ b/spid_cie_oidc/__init__.py @@ -1 +1 @@ -__version__ = "1.3.0" +__version__ = "1.3.1" From 22381842391ada11826e9fe6316941d0278a3faf Mon Sep 17 00:00:00 2001 From: Glauco <37829079+rglauco@users.noreply.github.com> Date: Wed, 7 Feb 2024 09:59:17 +0100 Subject: [PATCH 05/10] fix: corrected proposed change --- spid_cie_oidc/provider/views/__init__.py | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/spid_cie_oidc/provider/views/__init__.py b/spid_cie_oidc/provider/views/__init__.py index 3ef40868..b29269af 100644 --- a/spid_cie_oidc/provider/views/__init__.py +++ b/spid_cie_oidc/provider/views/__init__.py @@ -397,13 +397,19 @@ def attributes_names_to_release(self, request, session: OidcSession) -> dict: ) def get_client_organisation_name(self, tc): - fed_metadata = tc.metadata.get("federation_entity", {}) - name = fed_metadata.get("organization_name", "") - if not name: - op_metadata = tc.metadata.get("openid_relying_party", {}) - name = op_metadata.get("organization_name", "") - if not name: - name = op_metadata.get("client_name", "") - if not name: - name = op_metadata.get("client_id", "") + global name + rp_metadata = ( + tc.metadata.get( + "federation_entity", {} + ) or + tc.metadata.get( + "openid_relying_party", {} + ) + ) + if rp_metadata: + name = ( + rp_metadata.get("organization_name", "") or + rp_metadata.get("client_name", "") or + rp_metadata.get("client_id", "") + ) return name From 0f1c63afa32e7907b6fff8176b36a3c3d545d177 Mon Sep 17 00:00:00 2001 From: Glauco <37829079+rglauco@users.noreply.github.com> Date: Wed, 7 Feb 2024 10:51:36 +0100 Subject: [PATCH 06/10] fix: scope issue --- spid_cie_oidc/provider/views/__init__.py | 1 - 1 file changed, 1 deletion(-) diff --git a/spid_cie_oidc/provider/views/__init__.py b/spid_cie_oidc/provider/views/__init__.py index b29269af..de69e1f7 100644 --- a/spid_cie_oidc/provider/views/__init__.py +++ b/spid_cie_oidc/provider/views/__init__.py @@ -397,7 +397,6 @@ def attributes_names_to_release(self, request, session: OidcSession) -> dict: ) def get_client_organisation_name(self, tc): - global name rp_metadata = ( tc.metadata.get( "federation_entity", {} From e4e61f6af9d21dece02307c2b0959c9339608ac8 Mon Sep 17 00:00:00 2001 From: Glauco <37829079+rglauco@users.noreply.github.com> Date: Wed, 7 Feb 2024 12:00:50 +0100 Subject: [PATCH 07/10] Update spid_cie_oidc/provider/views/consent_page_view.py Co-authored-by: Giuseppe De Marco --- spid_cie_oidc/provider/views/consent_page_view.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spid_cie_oidc/provider/views/consent_page_view.py b/spid_cie_oidc/provider/views/consent_page_view.py index 56ffd843..f639db23 100644 --- a/spid_cie_oidc/provider/views/consent_page_view.py +++ b/spid_cie_oidc/provider/views/consent_page_view.py @@ -56,7 +56,7 @@ def get(self, request, *args, **kwargs): context = { "form": self.get_consent_form()(), "session": session, - "client_organization_name": self.get_client_organisation_name(tc), + "client_organization_name": self.get_client_organization_name(tc), "user_claims": sorted(set(i18n_user_claims),), "redirect_uri": session.authz_request["redirect_uri"], "state": session.authz_request["state"] From d718b27eb896b589b22352828a90f70d2bdf8e81 Mon Sep 17 00:00:00 2001 From: Glauco <37829079+rglauco@users.noreply.github.com> Date: Wed, 7 Feb 2024 12:00:59 +0100 Subject: [PATCH 08/10] Update spid_cie_oidc/provider/views/__init__.py Co-authored-by: Giuseppe De Marco --- spid_cie_oidc/provider/views/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spid_cie_oidc/provider/views/__init__.py b/spid_cie_oidc/provider/views/__init__.py index de69e1f7..d154e661 100644 --- a/spid_cie_oidc/provider/views/__init__.py +++ b/spid_cie_oidc/provider/views/__init__.py @@ -396,7 +396,7 @@ def attributes_names_to_release(self, request, session: OidcSession) -> dict: filtered_user_claims=filtered_user_claims ) - def get_client_organisation_name(self, tc): + def get_client_organization_name(self, tc): rp_metadata = ( tc.metadata.get( "federation_entity", {} From b6e8a15b791cc325eb6f0049fbe456c240e82945 Mon Sep 17 00:00:00 2001 From: Glauco <37829079+rglauco@users.noreply.github.com> Date: Wed, 7 Feb 2024 12:01:12 +0100 Subject: [PATCH 09/10] Update spid_cie_oidc/provider/views/authz_request_view.py Co-authored-by: Giuseppe De Marco --- spid_cie_oidc/provider/views/authz_request_view.py | 6 ------ 1 file changed, 6 deletions(-) diff --git a/spid_cie_oidc/provider/views/authz_request_view.py b/spid_cie_oidc/provider/views/authz_request_view.py index b59d4cf2..91aa24b7 100644 --- a/spid_cie_oidc/provider/views/authz_request_view.py +++ b/spid_cie_oidc/provider/views/authz_request_view.py @@ -198,12 +198,6 @@ def get(self, request, *args, **kwargs): # stores the authz request in a hidden field in the form form = self.get_login_form()() - - # context = { - # "client_organization_name": tc.metadata.get( - # "client_name", self.payload["client_id"] - # ), - context = { "client_organization_name": self.get_client_organisation_name(tc), "hidden_form": AuthzHiddenForm(dict(authz_request_object=req)), From de5969c081d78862e8a888c5ae96843735f6b5dc Mon Sep 17 00:00:00 2001 From: Glauco <37829079+rglauco@users.noreply.github.com> Date: Wed, 7 Feb 2024 12:11:23 +0100 Subject: [PATCH 10/10] fix: reinstated method name --- spid_cie_oidc/provider/views/authz_request_view.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spid_cie_oidc/provider/views/authz_request_view.py b/spid_cie_oidc/provider/views/authz_request_view.py index 91aa24b7..76e3df86 100644 --- a/spid_cie_oidc/provider/views/authz_request_view.py +++ b/spid_cie_oidc/provider/views/authz_request_view.py @@ -199,7 +199,7 @@ def get(self, request, *args, **kwargs): # stores the authz request in a hidden field in the form form = self.get_login_form()() context = { - "client_organization_name": self.get_client_organisation_name(tc), + "client_organization_name": self.get_client_organization_name(tc), "hidden_form": AuthzHiddenForm(dict(authz_request_object=req)), "form": form, "redirect_uri": self.payload["redirect_uri"],