From a4147e0a9e454c91891dc2741cd616ea6b0f000a Mon Sep 17 00:00:00 2001 From: Guillaume Rousse Date: Tue, 21 Jan 2025 16:33:25 +0100 Subject: [PATCH 1/2] URL handling simplification declare only relative URLs in configuration, so as to fix registration when base URL contains a path (issue #179), and expose those endpoints to outer world by appending base URL when needed. This is much simpler than parsing absolute URLs, and more consistent with OIDC frontends behaviour. --- example/plugins/backends/saml2_backend.yaml.example | 4 ++-- src/satosa/backends/saml2.py | 12 ++++++------ 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/example/plugins/backends/saml2_backend.yaml.example b/example/plugins/backends/saml2_backend.yaml.example index 76f9406e..08eb6404 100644 --- a/example/plugins/backends/saml2_backend.yaml.example +++ b/example/plugins/backends/saml2_backend.yaml.example @@ -63,9 +63,9 @@ config: allow_unsolicited: true endpoints: assertion_consumer_service: - - [//acs/post, 'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST'] + - [/acs/post, 'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST'] discovery_response: - - [//disco, 'urn:oasis:names:tc:SAML:profiles:SSO:idp-discovery-protocol'] + - [/disco, 'urn:oasis:names:tc:SAML:profiles:SSO:idp-discovery-protocol'] # name_id_format: a list of strings to set the element in SP metadata # name_id_policy_format: a string to set the Format attribute in the NameIDPolicy element diff --git a/src/satosa/backends/saml2.py b/src/satosa/backends/saml2.py index 8be4572d..3b120df7 100644 --- a/src/satosa/backends/saml2.py +++ b/src/satosa/backends/saml2.py @@ -209,7 +209,7 @@ def disco_query(self, context): :return: Response """ endpoints = self.sp.config.getattr("endpoints", "sp") - return_url = endpoints["discovery_response"][0][0] + return_url = "{}/{}".format(self.base_url, endpoints["discovery_response"][0][0]) disco_url = ( context.get_decoration(SAMLBackend.KEY_SAML_DISCOVERY_SERVICE_URL) @@ -303,10 +303,11 @@ def authn_request(self, context, entity_id): try: acs_endp, response_binding = self._get_acs(context) + acs_endp_url = "{}/{}".format(self.base_url, acs_endp) relay_state = util.rndstr() req_id, binding, http_info = self.sp.prepare_for_negotiated_authenticate( entityid=entity_id, - assertion_consumer_service_url=acs_endp, + assertion_consumer_service_url=acs_endp_url, response_binding=response_binding, relay_state=relay_state, **kwargs, @@ -588,8 +589,7 @@ def register_endpoints(self): url_map = [] sp_endpoints = self.sp.config.getattr("endpoints", "sp") for endp, binding in sp_endpoints["assertion_consumer_service"]: - parsed_endp = urlparse(endp) - url_map.append(("^%s$" % parsed_endp.path[1:], functools.partial(self.authn_response, binding=binding))) + url_map.append(("^%s$" % endp, functools.partial(self.authn_response, binding=binding))) if binding == BINDING_HTTP_REDIRECT: msg = " ".join( [ @@ -607,9 +607,8 @@ def register_endpoints(self): if self.discosrv: for endp, binding in sp_endpoints["discovery_response"]: - parsed_endp = urlparse(endp) url_map.append( - ("^%s$" % parsed_endp.path[1:], self.disco_response)) + ("^%s$" % endp, self.disco_response)) if self.expose_entityid_endpoint(): logger.debug("Exposing backend entity endpoint = {}".format(self.sp.config.entityid)) @@ -621,6 +620,7 @@ def register_endpoints(self): url_map.append( ("^%s/%s$" % (self.name, "reload-metadata"), self._reload_metadata)) + logger.debug(f"Loaded SAML2 endpoints: {url_map}") return url_map def _reload_metadata(self, context): From ee5c0a9c218f131d231c8fd8540e04e9decb6b30 Mon Sep 17 00:00:00 2001 From: Guillaume Rousse Date: Wed, 22 Jan 2025 10:43:20 +0100 Subject: [PATCH 2/2] make metadata endpoints configurable as others Rather have a working metadata exposure endpoint registration, whatever base url is, than try to deduce it from entityID. --- example/plugins/backends/saml2_backend.yaml.example | 2 ++ src/satosa/backends/saml2.py | 8 +++----- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/example/plugins/backends/saml2_backend.yaml.example b/example/plugins/backends/saml2_backend.yaml.example index 08eb6404..a9dc0c0e 100644 --- a/example/plugins/backends/saml2_backend.yaml.example +++ b/example/plugins/backends/saml2_backend.yaml.example @@ -66,6 +66,8 @@ config: - [/acs/post, 'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST'] discovery_response: - [/disco, 'urn:oasis:names:tc:SAML:profiles:SSO:idp-discovery-protocol'] + metadata_exposal: /proxy_saml2_backend.xml + metadata_reload: /reload-metadata # name_id_format: a list of strings to set the element in SP metadata # name_id_policy_format: a string to set the Format attribute in the NameIDPolicy element diff --git a/src/satosa/backends/saml2.py b/src/satosa/backends/saml2.py index 3b120df7..b0ecfa86 100644 --- a/src/satosa/backends/saml2.py +++ b/src/satosa/backends/saml2.py @@ -611,14 +611,12 @@ def register_endpoints(self): ("^%s$" % endp, self.disco_response)) if self.expose_entityid_endpoint(): - logger.debug("Exposing backend entity endpoint = {}".format(self.sp.config.entityid)) - parsed_entity_id = urlparse(self.sp.config.entityid) - url_map.append(("^{0}".format(parsed_entity_id.path[1:]), - self._metadata_endpoint)) + url_map.append( + ("^%s$" % sp_endpoints["metadata_exposal"], self._metadata_endpoint)) if self.enable_metadata_reload(): url_map.append( - ("^%s/%s$" % (self.name, "reload-metadata"), self._reload_metadata)) + ("^%s$" % sp_endpoints["metadata_reload"], self._reload_metadata)) logger.debug(f"Loaded SAML2 endpoints: {url_map}") return url_map