providers/saml: make SAML metadata generation consistent
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
This commit is contained in:
parent
25910bb577
commit
1363226697
|
@ -1,4 +1,5 @@
|
||||||
"""SAML Identity Provider Metadata Processor"""
|
"""SAML Identity Provider Metadata Processor"""
|
||||||
|
from hashlib import sha256
|
||||||
from typing import Iterator, Optional
|
from typing import Iterator, Optional
|
||||||
|
|
||||||
import xmlsec # nosec
|
import xmlsec # nosec
|
||||||
|
@ -7,7 +8,6 @@ from django.urls import reverse
|
||||||
from lxml.etree import Element, SubElement, tostring # nosec
|
from lxml.etree import Element, SubElement, tostring # nosec
|
||||||
|
|
||||||
from authentik.providers.saml.models import SAMLProvider
|
from authentik.providers.saml.models import SAMLProvider
|
||||||
from authentik.providers.saml.utils import get_random_id
|
|
||||||
from authentik.providers.saml.utils.encoding import strip_pem_header
|
from authentik.providers.saml.utils.encoding import strip_pem_header
|
||||||
from authentik.sources.saml.processors.constants import (
|
from authentik.sources.saml.processors.constants import (
|
||||||
DIGEST_ALGORITHM_TRANSLATION_MAP,
|
DIGEST_ALGORITHM_TRANSLATION_MAP,
|
||||||
|
@ -35,7 +35,7 @@ class MetadataProcessor:
|
||||||
self.provider = provider
|
self.provider = provider
|
||||||
self.http_request = request
|
self.http_request = request
|
||||||
self.force_binding = None
|
self.force_binding = None
|
||||||
self.xml_id = get_random_id()
|
self.xml_id = sha256(f"{provider.name}-{provider.pk}".encode("ascii")).hexdigest()
|
||||||
|
|
||||||
def get_signing_key_descriptor(self) -> Optional[Element]:
|
def get_signing_key_descriptor(self) -> Optional[Element]:
|
||||||
"""Get Signing KeyDescriptor, if enabled for the provider"""
|
"""Get Signing KeyDescriptor, if enabled for the provider"""
|
||||||
|
|
|
@ -1,10 +1,12 @@
|
||||||
"""Test Service-Provider Metadata Parser"""
|
"""Test Service-Provider Metadata Parser"""
|
||||||
# flake8: noqa
|
# flake8: noqa
|
||||||
|
|
||||||
from django.test import TestCase
|
from django.test import RequestFactory, TestCase
|
||||||
|
|
||||||
|
from authentik.core.models import Application
|
||||||
from authentik.core.tests.utils import create_test_cert, create_test_flow
|
from authentik.core.tests.utils import create_test_cert, create_test_flow
|
||||||
from authentik.providers.saml.models import SAMLBindings, SAMLPropertyMapping
|
from authentik.providers.saml.models import SAMLBindings, SAMLPropertyMapping, SAMLProvider
|
||||||
|
from authentik.providers.saml.processors.metadata import MetadataProcessor
|
||||||
from authentik.providers.saml.processors.metadata_parser import ServiceProviderMetadataParser
|
from authentik.providers.saml.processors.metadata_parser import ServiceProviderMetadataParser
|
||||||
|
|
||||||
METADATA_SIMPLE = """<?xml version="1.0"?>
|
METADATA_SIMPLE = """<?xml version="1.0"?>
|
||||||
|
@ -66,6 +68,23 @@ class TestServiceProviderMetadataParser(TestCase):
|
||||||
|
|
||||||
def setUp(self) -> None:
|
def setUp(self) -> None:
|
||||||
self.flow = create_test_flow()
|
self.flow = create_test_flow()
|
||||||
|
self.factory = RequestFactory()
|
||||||
|
|
||||||
|
def test_consistent(self):
|
||||||
|
"""Test that metadata generation is consistent"""
|
||||||
|
provider = SAMLProvider.objects.create(
|
||||||
|
name="test",
|
||||||
|
authorization_flow=self.flow,
|
||||||
|
)
|
||||||
|
Application.objects.create(
|
||||||
|
name="test",
|
||||||
|
slug="test",
|
||||||
|
provider=provider,
|
||||||
|
)
|
||||||
|
request = self.factory.get("/")
|
||||||
|
metadata_a = MetadataProcessor(provider, request).build_entity_descriptor()
|
||||||
|
metadata_b = MetadataProcessor(provider, request).build_entity_descriptor()
|
||||||
|
self.assertEqual(metadata_a, metadata_b)
|
||||||
|
|
||||||
def test_simple(self):
|
def test_simple(self):
|
||||||
"""Test simple metadata without Signing"""
|
"""Test simple metadata without Signing"""
|
||||||
|
|
|
@ -29,6 +29,19 @@ class TestMetadataProcessor(TestCase):
|
||||||
schema = etree.XMLSchema(etree.parse("xml/saml-schema-metadata-2.0.xsd")) # nosec
|
schema = etree.XMLSchema(etree.parse("xml/saml-schema-metadata-2.0.xsd")) # nosec
|
||||||
self.assertTrue(schema.validate(metadata))
|
self.assertTrue(schema.validate(metadata))
|
||||||
|
|
||||||
|
def test_metadata_consistent(self):
|
||||||
|
"""Test Metadata generation being consistent (xml stays the same)"""
|
||||||
|
source = SAMLSource.objects.create(
|
||||||
|
slug="provider",
|
||||||
|
issuer="authentik",
|
||||||
|
signing_kp=create_test_cert(),
|
||||||
|
pre_authentication_flow=create_test_flow(),
|
||||||
|
)
|
||||||
|
request = self.factory.get("/")
|
||||||
|
xml_a = MetadataProcessor(source, request).build_entity_descriptor()
|
||||||
|
xml_b = MetadataProcessor(source, request).build_entity_descriptor()
|
||||||
|
self.assertEqual(xml_a, xml_b)
|
||||||
|
|
||||||
def test_metadata(self):
|
def test_metadata(self):
|
||||||
"""Test Metadata generation being valid"""
|
"""Test Metadata generation being valid"""
|
||||||
source = SAMLSource.objects.create(
|
source = SAMLSource.objects.create(
|
||||||
|
|
Reference in New Issue