mirror of
https://github.com/goauthentik/authentik
synced 2026-05-05 22:52:42 +02:00
Compare commits
1 Commits
next
...
generate-i
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1d42baf212 |
@@ -39,6 +39,55 @@ def post_save_application(sender: type[Model], instance, created: bool, **_):
|
||||
cache.delete_many(keys)
|
||||
|
||||
|
||||
@receiver(post_save, sender=Application)
|
||||
def post_save_application_saml_issuer(sender: type[Model], instance: Application, **_):
|
||||
"""Generate SAML provider issuer when application is linked to a SAML provider"""
|
||||
from authentik.lib.config import CONFIG
|
||||
from authentik.providers.saml.models import SAMLProvider
|
||||
|
||||
LOGGER.debug("Application saved, checking for SAML issuer generation", app=instance.slug)
|
||||
|
||||
# Only process if application has a provider
|
||||
if not instance.provider:
|
||||
LOGGER.debug("Application has no provider, skipping", app=instance.slug)
|
||||
return
|
||||
|
||||
# Check if provider is a SAML provider by trying to access the samlprovider attribute
|
||||
try:
|
||||
provider = instance.provider.samlprovider
|
||||
except (AttributeError, SAMLProvider.DoesNotExist):
|
||||
LOGGER.debug(
|
||||
"Provider is not SAML, skipping",
|
||||
app=instance.slug,
|
||||
provider_type=type(instance.provider).__name__,
|
||||
)
|
||||
return
|
||||
|
||||
# Only set issuer if it's null
|
||||
if provider.issuer:
|
||||
LOGGER.debug(
|
||||
"Issuer already set, skipping",
|
||||
app=instance.slug,
|
||||
provider=provider.name,
|
||||
issuer=provider.issuer,
|
||||
)
|
||||
return
|
||||
|
||||
# Generate the issuer URL
|
||||
scheme = "https" if not CONFIG.get_bool("authentik.debug", False) else "http"
|
||||
domain = CONFIG.get("server.domain", "localhost:9000")
|
||||
path = f"/application/saml/{instance.slug}/"
|
||||
provider.issuer = f"{scheme}://{domain}{path}"
|
||||
provider.save()
|
||||
|
||||
LOGGER.info(
|
||||
"Generated issuer for SAML provider",
|
||||
provider=provider.name,
|
||||
application=instance.slug,
|
||||
issuer=provider.issuer,
|
||||
)
|
||||
|
||||
|
||||
@receiver(user_logged_in)
|
||||
def user_logged_in_session(sender, request: HttpRequest, user: User, **_):
|
||||
"""Create an AuthenticatedSession from request"""
|
||||
|
||||
@@ -211,7 +211,9 @@ class SAMLProviderSerializer(ProviderSerializer):
|
||||
"url_slo_post",
|
||||
"url_slo_redirect",
|
||||
]
|
||||
extra_kwargs = ProviderSerializer.Meta.extra_kwargs
|
||||
extra_kwargs = ProviderSerializer.Meta.extra_kwargs | {
|
||||
"issuer": {"required": False, "allow_blank": True, "allow_null": True}
|
||||
}
|
||||
|
||||
|
||||
class SAMLMetadataSerializer(PassiveSerializer):
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
# Generated by Django 5.2.7 on 2025-11-05 03:31
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
("authentik_providers_saml", "0020_samlprovider_logout_method_and_more"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name="samlprovider",
|
||||
name="issuer",
|
||||
field=models.TextField(
|
||||
blank=True,
|
||||
default=None,
|
||||
help_text="Also known as EntityID. When left empty, defaults to: https://<your-domain>/application/saml/<application-slug>/",
|
||||
null=True,
|
||||
),
|
||||
),
|
||||
]
|
||||
@@ -69,7 +69,14 @@ class SAMLProvider(Provider):
|
||||
"no audience restriction will be added."
|
||||
),
|
||||
)
|
||||
issuer = models.TextField(help_text=_("Also known as EntityID"), default="authentik")
|
||||
issuer = models.TextField(
|
||||
blank=True,
|
||||
null=True,
|
||||
default=None,
|
||||
help_text=_(
|
||||
"Also known as EntityID. When left empty, defaults to: https://<your-domain>/application/saml/<application-slug>/"
|
||||
),
|
||||
)
|
||||
sp_binding = models.TextField(
|
||||
choices=SAMLBindings.choices,
|
||||
default=SAMLBindings.REDIRECT,
|
||||
|
||||
@@ -9409,10 +9409,12 @@
|
||||
"description": "Value of the audience restriction field of the assertion. When left empty, no audience restriction will be added."
|
||||
},
|
||||
"issuer": {
|
||||
"type": "string",
|
||||
"minLength": 1,
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
],
|
||||
"title": "Issuer",
|
||||
"description": "Also known as EntityID"
|
||||
"description": "Also known as EntityID. When left empty, defaults to: https://<your-domain>/application/saml/<application-slug>/"
|
||||
},
|
||||
"assertion_valid_not_before": {
|
||||
"type": "string",
|
||||
|
||||
11
schema.yml
11
schema.yml
@@ -45476,8 +45476,8 @@ components:
|
||||
left empty, no audience restriction will be added.
|
||||
issuer:
|
||||
type: string
|
||||
minLength: 1
|
||||
description: Also known as EntityID
|
||||
nullable: true
|
||||
description: 'Also known as EntityID. When left empty, defaults to: https://<your-domain>/application/saml/<application-slug>/'
|
||||
assertion_valid_not_before:
|
||||
type: string
|
||||
minLength: 1
|
||||
@@ -48663,7 +48663,8 @@ components:
|
||||
left empty, no audience restriction will be added.
|
||||
issuer:
|
||||
type: string
|
||||
description: Also known as EntityID
|
||||
nullable: true
|
||||
description: 'Also known as EntityID. When left empty, defaults to: https://<your-domain>/application/saml/<application-slug>/'
|
||||
assertion_valid_not_before:
|
||||
type: string
|
||||
description: 'Assertion valid not before current time + this value (Format:
|
||||
@@ -48859,8 +48860,8 @@ components:
|
||||
left empty, no audience restriction will be added.
|
||||
issuer:
|
||||
type: string
|
||||
minLength: 1
|
||||
description: Also known as EntityID
|
||||
nullable: true
|
||||
description: 'Also known as EntityID. When left empty, defaults to: https://<your-domain>/application/saml/<application-slug>/'
|
||||
assertion_valid_not_before:
|
||||
type: string
|
||||
minLength: 1
|
||||
|
||||
@@ -33,7 +33,7 @@ function renderSAMLOverview(rawProvider: OneOfProvider) {
|
||||
return renderSummary("SAML", provider.name, [
|
||||
[msg("ACS URL"), provider.acsUrl],
|
||||
[msg("Audience"), provider.audience || "-"],
|
||||
[msg("Issuer"), provider.issuer],
|
||||
[msg("Issuer"), provider.issuer || "-"],
|
||||
]);
|
||||
}
|
||||
|
||||
|
||||
@@ -169,14 +169,6 @@ export function renderForm({
|
||||
required
|
||||
.errorMessages=${errors.acsUrl}
|
||||
></ak-text-input>
|
||||
<ak-text-input
|
||||
label=${msg("Issuer")}
|
||||
name="issuer"
|
||||
value="${provider.issuer || "authentik"}"
|
||||
required
|
||||
.errorMessages=${errors.issuer}
|
||||
help=${msg("Also known as EntityID.")}
|
||||
></ak-text-input>
|
||||
<ak-radio-input
|
||||
label=${msg("Service Provider Binding")}
|
||||
name="spBinding"
|
||||
@@ -411,6 +403,15 @@ export function renderForm({
|
||||
"When using IDP-initiated logins, the relay state will be set to this value.",
|
||||
)}
|
||||
></ak-text-input>
|
||||
<ak-text-input
|
||||
label=${msg("EntityID/Issuer override")}
|
||||
name="issuer"
|
||||
value="${ifDefined(provider.issuer ?? undefined)}"
|
||||
.errorMessages=${errors.issuer}
|
||||
help=${msg(
|
||||
"Input a value to set a custom EntityID/Issuer. defaults is https://<your-domain>/application/saml/<application-slug>/",
|
||||
)}
|
||||
></ak-text-input>
|
||||
<ak-form-element-horizontal
|
||||
label=${msg("Default NameID Policy")}
|
||||
required
|
||||
|
||||
@@ -390,7 +390,9 @@ export class SAMLProviderViewPage extends AKElement {
|
||||
class="pf-c-form-control"
|
||||
readonly
|
||||
type="text"
|
||||
value="${ifDefined(this.provider?.issuer)}"
|
||||
value="${ifDefined(
|
||||
this.provider?.issuer ?? undefined,
|
||||
)}"
|
||||
/>
|
||||
</div>
|
||||
<div class="pf-c-form__group">
|
||||
|
||||
Reference in New Issue
Block a user