diff --git a/authentik/providers/saml/processors/metadata.py b/authentik/providers/saml/processors/metadata.py index 6e7401a4a..cd87ad2f5 100644 --- a/authentik/providers/saml/processors/metadata.py +++ b/authentik/providers/saml/processors/metadata.py @@ -172,4 +172,4 @@ class MetadataProcessor: if self.provider.signing_kp: self._sign(entity_descriptor) - return tostring(entity_descriptor, pretty_print=True).decode() + return tostring(entity_descriptor).decode() diff --git a/authentik/providers/saml/tests/fixtures/cert.pem b/authentik/providers/saml/tests/fixtures/cert.pem new file mode 100644 index 000000000..e58e0d49a --- /dev/null +++ b/authentik/providers/saml/tests/fixtures/cert.pem @@ -0,0 +1,19 @@ +-----BEGIN CERTIFICATE----- +MIIDBzCCAe+gAwIBAgIQR8PqIN59R5mRygzU9JfD2TANBgkqhkiG9w0BAQsFADAr +MSkwJwYDVQQDDCBwYXNzYm9vayBTZWxmLXNpZ25lZCBDZXJ0aWZpY2F0ZTAeFw0y +MDA3MDUxMTEzMTRaFw0yMTA3MDYxMTEzMTRaMFQxKTAnBgNVBAMMIHBhc3Nib29r +IFNlbGYtc2lnbmVkIENlcnRpZmljYXRlMREwDwYDVQQKDAhwYXNzYm9vazEUMBIG +A1UECwwLU2VsZi1zaWduZWQwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB +AQC89aKl+gUw7X0d25LY5PQ0DuOlrIQf1iaY/X4uM1FNAaMfAnd653EE+ugerZWv +AtRGke2QElVgsvvGfMN6XfH/zSWxkklvXPsuM2HfW6Yv8FcaQRTB2jXBUzU6wNjw +F8V8TdFPpbVzQxXOvJyP8Z2YhUNRjy0OQzTV5bD21b2fhpWcNCCSJxIeZQxKjwQN +pt6xiGt0JXODgE8hp7psrKBMYa2O3MAmdCu1b0ixbfkam0Vm9vDHUyjRi2N9S7lk +iIP2fYEDi0v0zRq9/yV/0MEel4towY+WcNnLvKTsww80vFrgUI4K0r4bS9uBWZaC +lvycE0ZSMYHZG6TZBCUtEd2JAgMBAAEwDQYJKoZIhvcNAQELBQADggEBAFMbcuq8 +oL2tfvBFMktv722r2FbbRXs7ky4IE2m42eaGEuhgdmrLsHaH4m3X+1TZgCufMGgo +F8iVKQmpeaPSCDPKGW+yue+HLqCk5PIeQISDrEUwWNLx8lza7tm9Xdr1B3Q8/jxv +1qtokhzhaBkCvYy92gvIgio5QaFKaFOSIp2Crrhh+R+uvmtronKe8RPx6XEk4EaA +vXAfgGUV+xoQ9b54mt8gBwmZuLz86vIQBFSjOmPXEWYHe3FXAsB6i5eJMXtdBF7C +3VbL3wBqOqddBPQ6+ojY+cUmNqVYbtXmAcjIveoJDi8Rs4F5pmlhGahnMgW8mqYt +bHlUY7ytSUTowXA= +-----END CERTIFICATE----- \ No newline at end of file diff --git a/authentik/providers/saml/tests/fixtures/cert.xml b/authentik/providers/saml/tests/fixtures/cert.xml new file mode 100644 index 000000000..bfd8b7af3 --- /dev/null +++ b/authentik/providers/saml/tests/fixtures/cert.xml @@ -0,0 +1,18 @@ + + + + + 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 + + + + urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress + + + diff --git a/authentik/providers/saml/tests/fixtures/simple.xml b/authentik/providers/saml/tests/fixtures/simple.xml new file mode 100644 index 000000000..678461d31 --- /dev/null +++ b/authentik/providers/saml/tests/fixtures/simple.xml @@ -0,0 +1,13 @@ + + + + urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified + + + + diff --git a/authentik/providers/saml/tests/test_api.py b/authentik/providers/saml/tests/test_api.py index 392e2dff0..af103d8a3 100644 --- a/authentik/providers/saml/tests/test_api.py +++ b/authentik/providers/saml/tests/test_api.py @@ -11,7 +11,7 @@ from authentik.core.tests.utils import create_test_admin_user, create_test_flow from authentik.flows.models import FlowDesignation from authentik.lib.generators import generate_id from authentik.providers.saml.models import SAMLPropertyMapping, SAMLProvider -from authentik.providers.saml.tests.test_metadata import METADATA_SIMPLE +from authentik.providers.saml.tests.test_metadata import load_fixture class TestSAMLProviderAPI(APITestCase): @@ -82,7 +82,7 @@ class TestSAMLProviderAPI(APITestCase): def test_import_success(self): """Test metadata import (success case)""" with TemporaryFile() as metadata: - metadata.write(METADATA_SIMPLE.encode()) + metadata.write(load_fixture("fixtures/simple.xml").encode()) metadata.seek(0) response = self.client.post( reverse("authentik_api:samlprovider-import-metadata"), diff --git a/authentik/providers/saml/tests/test_metadata.py b/authentik/providers/saml/tests/test_metadata.py index b7cf21536..9ee444bfd 100644 --- a/authentik/providers/saml/tests/test_metadata.py +++ b/authentik/providers/saml/tests/test_metadata.py @@ -1,66 +1,23 @@ """Test Service-Provider Metadata Parser""" -# flake8: noqa +from pathlib import Path +import xmlsec +from defusedxml.lxml import fromstring 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.lib.generators import generate_id 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.sources.saml.processors.constants import NS_MAP -METADATA_SIMPLE = """ - - - urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified - - -""" - -METADATA_CERT = """ - - - - dPEwDuMayrdAgjhYvtiy3GTcP0n+BDi3sX+aistTDac=MMspOlqURPLT2ELAD5RRHw4mBIWBGWAEedwMM6Dh7kzhJE/1z+dNgobM8e1Lr9Ztd/ygW7oUfwfbUqS8OVCxdI+fJtzai0Jm08/rq8VpNEZqTfALNQqlGDD2Uma63/8iFycrhYkaY8feoyT0ZfHTNuMDxHjtl1l52+q+1mx6ax5w9z/WzuSKBTndg+Gjh0XTN0ynI136MgXrJg4dBFtkIKq9u6PlJW42C+uqAoRoi29Vil6mT/dgctS2ZB118nGFeryN4oi2zgM9lkmWW6E5YtPdQxggKJqR8Zl+XnyHt3nh1X7uWN+691lXO6LG1YXtagD/BSMeUnfMV/dLCptv3w== -MIIDBzCCAe+gAwIBAgIQR8PqIN59R5mRygzU9JfD2TANBgkqhkiG9w0BAQsFADArMSkwJwYDVQQDDCBwYXNzYm9vayBTZWxmLXNpZ25lZCBDZXJ0aWZpY2F0ZTAeFw0yMDA3MDUxMTEzMTRaFw0yMTA3MDYxMTEzMTRaMFQxKTAnBgNVBAMMIHBhc3Nib29rIFNlbGYtc2lnbmVkIENlcnRpZmljYXRlMREwDwYDVQQKDAhwYXNzYm9vazEUMBIGA1UECwwLU2VsZi1zaWduZWQwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC89aKl+gUw7X0d25LY5PQ0DuOlrIQf1iaY/X4uM1FNAaMfAnd653EE+ugerZWvAtRGke2QElVgsvvGfMN6XfH/zSWxkklvXPsuM2HfW6Yv8FcaQRTB2jXBUzU6wNjwF8V8TdFPpbVzQxXOvJyP8Z2YhUNRjy0OQzTV5bD21b2fhpWcNCCSJxIeZQxKjwQNpt6xiGt0JXODgE8hp7psrKBMYa2O3MAmdCu1b0ixbfkam0Vm9vDHUyjRi2N9S7lkiIP2fYEDi0v0zRq9/yV/0MEel4towY+WcNnLvKTsww80vFrgUI4K0r4bS9uBWZaClvycE0ZSMYHZG6TZBCUtEd2JAgMBAAEwDQYJKoZIhvcNAQELBQADggEBAFMbcuq8oL2tfvBFMktv722r2FbbRXs7ky4IE2m42eaGEuhgdmrLsHaH4m3X+1TZgCufMGgoF8iVKQmpeaPSCDPKGW+yue+HLqCk5PIeQISDrEUwWNLx8lza7tm9Xdr1B3Q8/jxv1qtokhzhaBkCvYy92gvIgio5QaFKaFOSIp2Crrhh+R+uvmtronKe8RPx6XEk4EaAvXAfgGUV+xoQ9b54mt8gBwmZuLz86vIQBFSjOmPXEWYHe3FXAsB6i5eJMXtdBF7C3VbL3wBqOqddBPQ6+ojY+cUmNqVYbtXmAcjIveoJDi8Rs4F5pmlhGahnMgW8mqYtbHlUY7ytSUTowXA= - - - - - MIIDBzCCAe+gAwIBAgIQR8PqIN59R5mRygzU9JfD2TANBgkqhkiG9w0BAQsFADArMSkwJwYDVQQDDCBwYXNzYm9vayBTZWxmLXNpZ25lZCBDZXJ0aWZpY2F0ZTAeFw0yMDA3MDUxMTEzMTRaFw0yMTA3MDYxMTEzMTRaMFQxKTAnBgNVBAMMIHBhc3Nib29rIFNlbGYtc2lnbmVkIENlcnRpZmljYXRlMREwDwYDVQQKDAhwYXNzYm9vazEUMBIGA1UECwwLU2VsZi1zaWduZWQwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC89aKl+gUw7X0d25LY5PQ0DuOlrIQf1iaY/X4uM1FNAaMfAnd653EE+ugerZWvAtRGke2QElVgsvvGfMN6XfH/zSWxkklvXPsuM2HfW6Yv8FcaQRTB2jXBUzU6wNjwF8V8TdFPpbVzQxXOvJyP8Z2YhUNRjy0OQzTV5bD21b2fhpWcNCCSJxIeZQxKjwQNpt6xiGt0JXODgE8hp7psrKBMYa2O3MAmdCu1b0ixbfkam0Vm9vDHUyjRi2N9S7lkiIP2fYEDi0v0zRq9/yV/0MEel4towY+WcNnLvKTsww80vFrgUI4K0r4bS9uBWZaClvycE0ZSMYHZG6TZBCUtEd2JAgMBAAEwDQYJKoZIhvcNAQELBQADggEBAFMbcuq8oL2tfvBFMktv722r2FbbRXs7ky4IE2m42eaGEuhgdmrLsHaH4m3X+1TZgCufMGgoF8iVKQmpeaPSCDPKGW+yue+HLqCk5PIeQISDrEUwWNLx8lza7tm9Xdr1B3Q8/jxv1qtokhzhaBkCvYy92gvIgio5QaFKaFOSIp2Crrhh+R+uvmtronKe8RPx6XEk4EaAvXAfgGUV+xoQ9b54mt8gBwmZuLz86vIQBFSjOmPXEWYHe3FXAsB6i5eJMXtdBF7C3VbL3wBqOqddBPQ6+ojY+cUmNqVYbtXmAcjIveoJDi8Rs4F5pmlhGahnMgW8mqYtbHlUY7ytSUTowXA= - - - - urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress - - -""" - -CERT = """-----BEGIN CERTIFICATE----- -MIIDBzCCAe+gAwIBAgIQR8PqIN59R5mRygzU9JfD2TANBgkqhkiG9w0BAQsFADAr -MSkwJwYDVQQDDCBwYXNzYm9vayBTZWxmLXNpZ25lZCBDZXJ0aWZpY2F0ZTAeFw0y -MDA3MDUxMTEzMTRaFw0yMTA3MDYxMTEzMTRaMFQxKTAnBgNVBAMMIHBhc3Nib29r -IFNlbGYtc2lnbmVkIENlcnRpZmljYXRlMREwDwYDVQQKDAhwYXNzYm9vazEUMBIG -A1UECwwLU2VsZi1zaWduZWQwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB -AQC89aKl+gUw7X0d25LY5PQ0DuOlrIQf1iaY/X4uM1FNAaMfAnd653EE+ugerZWv -AtRGke2QElVgsvvGfMN6XfH/zSWxkklvXPsuM2HfW6Yv8FcaQRTB2jXBUzU6wNjw -F8V8TdFPpbVzQxXOvJyP8Z2YhUNRjy0OQzTV5bD21b2fhpWcNCCSJxIeZQxKjwQN -pt6xiGt0JXODgE8hp7psrKBMYa2O3MAmdCu1b0ixbfkam0Vm9vDHUyjRi2N9S7lk -iIP2fYEDi0v0zRq9/yV/0MEel4towY+WcNnLvKTsww80vFrgUI4K0r4bS9uBWZaC -lvycE0ZSMYHZG6TZBCUtEd2JAgMBAAEwDQYJKoZIhvcNAQELBQADggEBAFMbcuq8 -oL2tfvBFMktv722r2FbbRXs7ky4IE2m42eaGEuhgdmrLsHaH4m3X+1TZgCufMGgo -F8iVKQmpeaPSCDPKGW+yue+HLqCk5PIeQISDrEUwWNLx8lza7tm9Xdr1B3Q8/jxv -1qtokhzhaBkCvYy92gvIgio5QaFKaFOSIp2Crrhh+R+uvmtronKe8RPx6XEk4EaA -vXAfgGUV+xoQ9b54mt8gBwmZuLz86vIQBFSjOmPXEWYHe3FXAsB6i5eJMXtdBF7C -3VbL3wBqOqddBPQ6+ojY+cUmNqVYbtXmAcjIveoJDi8Rs4F5pmlhGahnMgW8mqYt -bHlUY7ytSUTowXA= ------END CERTIFICATE-----""" +def load_fixture(path: str, **kwargs) -> str: + """Load fixture""" + with open(Path(__file__).resolve().parent / Path(path), "r", encoding="utf-8") as _fixture: + return _fixture.read() class TestServiceProviderMetadataParser(TestCase): @@ -73,12 +30,12 @@ class TestServiceProviderMetadataParser(TestCase): def test_consistent(self): """Test that metadata generation is consistent""" provider = SAMLProvider.objects.create( - name="test", + name=generate_id(), authorization_flow=self.flow, ) Application.objects.create( - name="test", - slug="test", + name=generate_id(), + slug=generate_id(), provider=provider, ) request = self.factory.get("/") @@ -88,7 +45,7 @@ class TestServiceProviderMetadataParser(TestCase): def test_simple(self): """Test simple metadata without Signing""" - metadata = ServiceProviderMetadataParser().parse(METADATA_SIMPLE) + metadata = ServiceProviderMetadataParser().parse(load_fixture("fixtures/simple.xml")) provider = metadata.to_provider("test", self.flow) self.assertEqual(provider.acs_url, "http://localhost:8080/saml/acs") self.assertEqual(provider.issuer, "http://localhost:8080/saml/metadata") @@ -101,16 +58,48 @@ class TestServiceProviderMetadataParser(TestCase): def test_with_signing_cert(self): """Test Metadata with signing cert""" create_test_cert() - metadata = ServiceProviderMetadataParser().parse(METADATA_CERT) + metadata = ServiceProviderMetadataParser().parse(load_fixture("fixtures/cert.xml")) provider = metadata.to_provider("test", self.flow) self.assertEqual(provider.acs_url, "http://localhost:8080/apps/user_saml/saml/acs") self.assertEqual(provider.issuer, "http://localhost:8080/apps/user_saml/saml/metadata") self.assertEqual(provider.sp_binding, SAMLBindings.POST) - self.assertEqual(provider.verification_kp.certificate_data, CERT) + self.assertEqual( + provider.verification_kp.certificate_data, load_fixture("fixtures/cert.pem") + ) self.assertIsNotNone(provider.signing_kp) self.assertEqual(provider.audience, "") def test_with_signing_cert_invalid_signature(self): """Test Metadata with signing cert (invalid signature)""" with self.assertRaises(ValueError): - ServiceProviderMetadataParser().parse(METADATA_CERT.replace("/apps/user_saml", "")) + ServiceProviderMetadataParser().parse( + load_fixture("fixtures/cert.xml").replace("/apps/user_saml", "") + ) + + def test_signature(self): + """Test signature validation""" + provider = SAMLProvider.objects.create( + name=generate_id(), + authorization_flow=self.flow, + signing_kp=create_test_cert(), + ) + Application.objects.create( + name=generate_id(), + slug=generate_id(), + provider=provider, + ) + request = self.factory.get("/") + metadata = MetadataProcessor(provider, request).build_entity_descriptor() + + root = fromstring(metadata.encode()) + xmlsec.tree.add_ids(root, ["ID"]) + signature_nodes = root.xpath("/md:EntityDescriptor/ds:Signature", namespaces=NS_MAP) + signature_node = signature_nodes[0] + ctx = xmlsec.SignatureContext() + key = xmlsec.Key.from_memory( + provider.signing_kp.certificate_data, + xmlsec.constants.KeyDataFormatCertPem, + None, + ) + ctx.key = key + ctx.verify(signature_node) diff --git a/authentik/sources/saml/processors/metadata.py b/authentik/sources/saml/processors/metadata.py index d5939931e..4ea825710 100644 --- a/authentik/sources/saml/processors/metadata.py +++ b/authentik/sources/saml/processors/metadata.py @@ -84,4 +84,4 @@ class MetadataProcessor: self.http_request ) - return tostring(entity_descriptor, pretty_print=True).decode() + return tostring(entity_descriptor).decode() diff --git a/internal/outpost/proxyv2/application/session.go b/internal/outpost/proxyv2/application/session.go index 24a02e6f3..d5cb81718 100644 --- a/internal/outpost/proxyv2/application/session.go +++ b/internal/outpost/proxyv2/application/session.go @@ -110,7 +110,7 @@ func (a *Application) Logout(sub string) error { if err != nil { return err } - ser := redistore.GobSerializer{} + serializer := redistore.GobSerializer{} for _, key := range keys { v, err := pool.Do("GET", key) if err != nil { @@ -123,7 +123,7 @@ func (a *Application) Logout(sub string) error { continue } s := sessions.Session{} - err = ser.Deserialize(b, &s) + err = serializer.Deserialize(b, &s) if err != nil { a.log.WithError(err).Warning("failed to deserialize") continue