sources/saml: fix NameIDFormat descriptor in metadata generation (#11614)

* source/saml - Changed namespace of X509SSubjectName NameIDFormat

Under the SAML2 Core spec
(http://docs.oasis-open.org/security/saml/v2.0/saml-core-2.0-os.pdf)
8.3.3 the URI of the 5.509 Subject Name contains SAML:1.1 and not
SAML:2.0

* source/saml - Change NameIDFormat descriptor build logic to only append chosen format for the source.

* Merge diff
This commit is contained in:
Nicolas
2024-10-11 14:27:36 +02:00
committed by GitHub
parent fc7e78444f
commit 77c595a0fd
6 changed files with 37 additions and 27 deletions

View File

@ -0,0 +1,26 @@
# Generated by Django 5.0.9 on 2024-10-10 15:45
from django.db import migrations
from django.apps.registry import Apps
from django.db.backends.base.schema import BaseDatabaseSchemaEditor
def fix_X509SubjectName(apps: Apps, schema_editor: BaseDatabaseSchemaEditor):
db_alias = schema_editor.connection.alias
SAMLSource = apps.get_model("authentik_sources_saml", "SAMLSource")
SAMLSource.objects.using(db_alias).filter(
name_id_policy="urn:oasis:names:tc:SAML:2.0:nameid-format:X509SubjectName"
).update(name_id_policy="urn:oasis:names:tc:SAML:1.1:nameid-format:X509SubjectName")
class Migration(migrations.Migration):
dependencies = [
("authentik_sources_saml", "0016_samlsource_encryption_kp"),
]
operations = [
migrations.RunPython(fix_X509SubjectName),
]

View File

@ -19,7 +19,7 @@ NS_MAP = {
SAML_NAME_ID_FORMAT_EMAIL = "urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress"
SAML_NAME_ID_FORMAT_PERSISTENT = "urn:oasis:names:tc:SAML:2.0:nameid-format:persistent"
SAML_NAME_ID_FORMAT_UNSPECIFIED = "urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified"
SAML_NAME_ID_FORMAT_X509 = "urn:oasis:names:tc:SAML:2.0:nameid-format:X509SubjectName"
SAML_NAME_ID_FORMAT_X509 = "urn:oasis:names:tc:SAML:1.1:nameid-format:X509SubjectName"
SAML_NAME_ID_FORMAT_WINDOWS = "urn:oasis:names:tc:SAML:2.0:nameid-format:WindowsDomainQualifiedName"
SAML_NAME_ID_FORMAT_TRANSIENT = "urn:oasis:names:tc:SAML:2.0:nameid-format:transient"

View File

@ -1,6 +1,5 @@
"""SAML Service Provider Metadata Processor"""
from collections.abc import Iterator
from typing import Optional
from django.http import HttpRequest
@ -13,11 +12,6 @@ from authentik.sources.saml.processors.constants import (
NS_SAML_METADATA,
NS_SIGNATURE,
SAML_BINDING_POST,
SAML_NAME_ID_FORMAT_EMAIL,
SAML_NAME_ID_FORMAT_PERSISTENT,
SAML_NAME_ID_FORMAT_TRANSIENT,
SAML_NAME_ID_FORMAT_WINDOWS,
SAML_NAME_ID_FORMAT_X509,
)
@ -60,19 +54,10 @@ class MetadataProcessor:
return key_descriptor
return None
def get_name_id_formats(self) -> Iterator[Element]:
"""Get compatible NameID Formats"""
formats = [
SAML_NAME_ID_FORMAT_EMAIL,
SAML_NAME_ID_FORMAT_PERSISTENT,
SAML_NAME_ID_FORMAT_X509,
SAML_NAME_ID_FORMAT_WINDOWS,
SAML_NAME_ID_FORMAT_TRANSIENT,
]
for name_id_format in formats:
element = Element(f"{{{NS_SAML_METADATA}}}NameIDFormat")
element.text = name_id_format
yield element
def get_name_id_format(self) -> Element:
element = Element(f"{{{NS_SAML_METADATA}}}NameIDFormat")
element.text = self.source.name_id_policy
return element
def build_entity_descriptor(self) -> str:
"""Build full EntityDescriptor"""
@ -92,8 +77,7 @@ class MetadataProcessor:
if encryption_descriptor is not None:
sp_sso_descriptor.append(encryption_descriptor)
for name_id_format in self.get_name_id_formats():
sp_sso_descriptor.append(name_id_format)
sp_sso_descriptor.append(self.get_name_id_format())
assertion_consumer_service = SubElement(
sp_sso_descriptor, f"{{{NS_SAML_METADATA}}}AssertionConsumerService"

View File

@ -7567,7 +7567,7 @@
"enum": [
"urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress",
"urn:oasis:names:tc:SAML:2.0:nameid-format:persistent",
"urn:oasis:names:tc:SAML:2.0:nameid-format:X509SubjectName",
"urn:oasis:names:tc:SAML:1.1:nameid-format:X509SubjectName",
"urn:oasis:names:tc:SAML:2.0:nameid-format:WindowsDomainQualifiedName",
"urn:oasis:names:tc:SAML:2.0:nameid-format:transient"
],

View File

@ -26141,9 +26141,9 @@ paths:
schema:
type: string
enum:
- urn:oasis:names:tc:SAML:1.1:nameid-format:X509SubjectName
- urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress
- urn:oasis:names:tc:SAML:2.0:nameid-format:WindowsDomainQualifiedName
- urn:oasis:names:tc:SAML:2.0:nameid-format:X509SubjectName
- urn:oasis:names:tc:SAML:2.0:nameid-format:persistent
- urn:oasis:names:tc:SAML:2.0:nameid-format:transient
description: |+
@ -42041,7 +42041,7 @@ components:
enum:
- urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress
- urn:oasis:names:tc:SAML:2.0:nameid-format:persistent
- urn:oasis:names:tc:SAML:2.0:nameid-format:X509SubjectName
- urn:oasis:names:tc:SAML:1.1:nameid-format:X509SubjectName
- urn:oasis:names:tc:SAML:2.0:nameid-format:WindowsDomainQualifiedName
- urn:oasis:names:tc:SAML:2.0:nameid-format:transient
type: string

View File

@ -402,9 +402,9 @@ export class SAMLSourceForm extends WithCapabilitiesConfig(BaseSourceForm<SAMLSo
${msg("Windows")}
</option>
<option
value=${NameIdPolicyEnum._20nameidFormatX509SubjectName}
value=${NameIdPolicyEnum._11nameidFormatX509SubjectName}
?selected=${this.instance?.nameIdPolicy ===
NameIdPolicyEnum._20nameidFormatX509SubjectName}
NameIdPolicyEnum._11nameidFormatX509SubjectName}
>
${msg("X509 Subject")}
</option>