From 6a3f7e45cfb4b5a2290cde1ad88ae61f91f4f17f Mon Sep 17 00:00:00 2001 From: Jens Langhammer Date: Sun, 5 Dec 2021 11:14:42 +0100 Subject: [PATCH] providers/saml: add ?force_binding to limit bindings for metadata endpoint Signed-off-by: Jens Langhammer --- authentik/providers/saml/api.py | 19 +++++++++++++++++-- .../providers/saml/processors/metadata.py | 4 ++++ schema.yml | 8 ++++++++ 3 files changed, 29 insertions(+), 2 deletions(-) diff --git a/authentik/providers/saml/api.py b/authentik/providers/saml/api.py index deda0400c..33a524e0f 100644 --- a/authentik/providers/saml/api.py +++ b/authentik/providers/saml/api.py @@ -36,6 +36,7 @@ from authentik.flows.models import Flow, FlowDesignation from authentik.providers.saml.models import SAMLPropertyMapping, SAMLProvider from authentik.providers.saml.processors.metadata import MetadataProcessor from authentik.providers.saml.processors.metadata_parser import ServiceProviderMetadataParser +from authentik.sources.saml.processors.constants import SAML_BINDING_POST, SAML_BINDING_REDIRECT LOGGER = get_logger() @@ -109,7 +110,19 @@ class SAMLProviderViewSet(UsedByMixin, ModelViewSet): name="download", location=OpenApiParameter.QUERY, type=OpenApiTypes.BOOL, - ) + ), + OpenApiParameter( + name="force_binding", + location=OpenApiParameter.QUERY, + type=OpenApiTypes.STR, + enum=[ + SAML_BINDING_REDIRECT, + SAML_BINDING_POST, + ], + description=( + "Optionally force the metadata to only include one binding." + ) + ), ], ) @action(methods=["GET"], detail=True, permission_classes=[AllowAny]) @@ -122,7 +135,9 @@ class SAMLProviderViewSet(UsedByMixin, ModelViewSet): except ValueError: raise Http404 try: - metadata = MetadataProcessor(provider, request).build_entity_descriptor() + proc = MetadataProcessor(provider, request) + proc.force_binding = request.query_params.get("force_binding", None) + metadata = proc.build_entity_descriptor() if "download" in request.query_params: response = HttpResponse(metadata, content_type="application/xml") response[ diff --git a/authentik/providers/saml/processors/metadata.py b/authentik/providers/saml/processors/metadata.py index 8a97e5f22..653299a57 100644 --- a/authentik/providers/saml/processors/metadata.py +++ b/authentik/providers/saml/processors/metadata.py @@ -29,10 +29,12 @@ class MetadataProcessor: provider: SAMLProvider http_request: HttpRequest + force_binding: Optional[str] def __init__(self, provider: SAMLProvider, request: HttpRequest): self.provider = provider self.http_request = request + self.force_binding = None self.xml_id = get_random_id() def get_signing_key_descriptor(self) -> Optional[Element]: @@ -79,6 +81,8 @@ class MetadataProcessor: ), } for binding, url in binding_url_map.items(): + if self.force_binding and self.force_binding != binding: + continue element = Element(f"{{{NS_SAML_METADATA}}}SingleSignOnService") element.attrib["Binding"] = binding element.attrib["Location"] = url diff --git a/schema.yml b/schema.yml index 28dae5da6..d241ac93d 100644 --- a/schema.yml +++ b/schema.yml @@ -11645,6 +11645,14 @@ paths: name: download schema: type: boolean + - in: query + name: force_binding + schema: + type: string + enum: + - urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST + - urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect + description: Optionally force the metadata to only include one binding. - in: path name: id schema: