sources/ldap: add optional tls verification certificate
closes #1875 Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
This commit is contained in:
@ -43,6 +43,7 @@ class LDAPSourceSerializer(SourceSerializer):
|
|||||||
model = LDAPSource
|
model = LDAPSource
|
||||||
fields = SourceSerializer.Meta.fields + [
|
fields = SourceSerializer.Meta.fields + [
|
||||||
"server_uri",
|
"server_uri",
|
||||||
|
"peer_certificate",
|
||||||
"bind_cn",
|
"bind_cn",
|
||||||
"bind_password",
|
"bind_password",
|
||||||
"start_tls",
|
"start_tls",
|
||||||
@ -73,11 +74,9 @@ class LDAPSourceViewSet(UsedByMixin, ModelViewSet):
|
|||||||
"name",
|
"name",
|
||||||
"slug",
|
"slug",
|
||||||
"enabled",
|
"enabled",
|
||||||
"authentication_flow",
|
|
||||||
"enrollment_flow",
|
|
||||||
"policy_engine_mode",
|
|
||||||
"server_uri",
|
"server_uri",
|
||||||
"bind_cn",
|
"bind_cn",
|
||||||
|
"peer_certificate",
|
||||||
"start_tls",
|
"start_tls",
|
||||||
"base_dn",
|
"base_dn",
|
||||||
"additional_user_dn",
|
"additional_user_dn",
|
||||||
|
|||||||
38
authentik/sources/ldap/migrations/0002_auto_20211203_0900.py
Normal file
38
authentik/sources/ldap/migrations/0002_auto_20211203_0900.py
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
# Generated by Django 3.2.9 on 2021-12-03 09:00
|
||||||
|
|
||||||
|
import django.db.models.deletion
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
import authentik.sources.ldap.models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
("authentik_crypto", "0003_certificatekeypair_managed"),
|
||||||
|
("authentik_sources_ldap", "0001_squashed_0012_auto_20210812_1703"),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AddField(
|
||||||
|
model_name="ldapsource",
|
||||||
|
name="peer_certificate",
|
||||||
|
field=models.ForeignKey(
|
||||||
|
default=None,
|
||||||
|
help_text="Optionally verify the LDAP Server's Certificate against the CA Chain in this keypair.",
|
||||||
|
null=True,
|
||||||
|
on_delete=django.db.models.deletion.SET_DEFAULT,
|
||||||
|
to="authentik_crypto.certificatekeypair",
|
||||||
|
),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name="ldapsource",
|
||||||
|
name="server_uri",
|
||||||
|
field=models.TextField(
|
||||||
|
validators=[
|
||||||
|
authentik.sources.ldap.models.MultiURLValidator(schemes=["ldap", "ldaps"])
|
||||||
|
],
|
||||||
|
verbose_name="Server URI",
|
||||||
|
),
|
||||||
|
),
|
||||||
|
]
|
||||||
@ -1,12 +1,14 @@
|
|||||||
"""authentik LDAP Models"""
|
"""authentik LDAP Models"""
|
||||||
|
from ssl import CERT_REQUIRED
|
||||||
from typing import Type
|
from typing import Type
|
||||||
|
|
||||||
from django.db import models
|
from django.db import models
|
||||||
from django.utils.translation import gettext_lazy as _
|
from django.utils.translation import gettext_lazy as _
|
||||||
from ldap3 import ALL, RANDOM, Connection, Server, ServerPool
|
from ldap3 import ALL, RANDOM, Connection, Server, ServerPool, Tls
|
||||||
from rest_framework.serializers import Serializer
|
from rest_framework.serializers import Serializer
|
||||||
|
|
||||||
from authentik.core.models import Group, PropertyMapping, Source
|
from authentik.core.models import Group, PropertyMapping, Source
|
||||||
|
from authentik.crypto.models import CertificateKeyPair
|
||||||
from authentik.lib.models import DomainlessURLValidator
|
from authentik.lib.models import DomainlessURLValidator
|
||||||
|
|
||||||
LDAP_TIMEOUT = 15
|
LDAP_TIMEOUT = 15
|
||||||
@ -30,6 +32,17 @@ class LDAPSource(Source):
|
|||||||
validators=[MultiURLValidator(schemes=["ldap", "ldaps"])],
|
validators=[MultiURLValidator(schemes=["ldap", "ldaps"])],
|
||||||
verbose_name=_("Server URI"),
|
verbose_name=_("Server URI"),
|
||||||
)
|
)
|
||||||
|
peer_certificate = models.ForeignKey(
|
||||||
|
CertificateKeyPair,
|
||||||
|
on_delete=models.SET_DEFAULT,
|
||||||
|
default=None,
|
||||||
|
null=True,
|
||||||
|
help_text=_(
|
||||||
|
"Optionally verify the LDAP Server's Certificate "
|
||||||
|
"against the CA Chain in this keypair."
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
bind_cn = models.TextField(verbose_name=_("Bind CN"), blank=True)
|
bind_cn = models.TextField(verbose_name=_("Bind CN"), blank=True)
|
||||||
bind_password = models.TextField(blank=True)
|
bind_password = models.TextField(blank=True)
|
||||||
start_tls = models.BooleanField(default=False, verbose_name=_("Enable Start TLS"))
|
start_tls = models.BooleanField(default=False, verbose_name=_("Enable Start TLS"))
|
||||||
@ -97,11 +110,19 @@ class LDAPSource(Source):
|
|||||||
def server(self) -> Server:
|
def server(self) -> Server:
|
||||||
"""Get LDAP Server/ServerPool"""
|
"""Get LDAP Server/ServerPool"""
|
||||||
servers = []
|
servers = []
|
||||||
|
tls = Tls()
|
||||||
|
if self.peer_certificate:
|
||||||
|
tls = Tls(ca_certs_data=self.peer_certificate.certificate_data, validate=CERT_REQUIRED)
|
||||||
|
kwargs = {
|
||||||
|
"get_info": ALL,
|
||||||
|
"connect_timeout": LDAP_TIMEOUT,
|
||||||
|
"tls": tls,
|
||||||
|
}
|
||||||
if "," in self.server_uri:
|
if "," in self.server_uri:
|
||||||
for server in self.server_uri.split(","):
|
for server in self.server_uri.split(","):
|
||||||
servers.append(Server(server, get_info=ALL, connect_timeout=LDAP_TIMEOUT))
|
servers.append(Server(server, **kwargs))
|
||||||
else:
|
else:
|
||||||
servers = [Server(self.server_uri, get_info=ALL, connect_timeout=LDAP_TIMEOUT)]
|
servers = [Server(self.server_uri, **kwargs)]
|
||||||
return ServerPool(servers, RANDOM, active=True, exhaust=True)
|
return ServerPool(servers, RANDOM, active=True, exhaust=True)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
|
|||||||
34
schema.yml
34
schema.yml
@ -12058,11 +12058,6 @@ paths:
|
|||||||
name: additional_user_dn
|
name: additional_user_dn
|
||||||
schema:
|
schema:
|
||||||
type: string
|
type: string
|
||||||
- in: query
|
|
||||||
name: authentication_flow
|
|
||||||
schema:
|
|
||||||
type: string
|
|
||||||
format: uuid
|
|
||||||
- in: query
|
- in: query
|
||||||
name: base_dn
|
name: base_dn
|
||||||
schema:
|
schema:
|
||||||
@ -12075,11 +12070,6 @@ paths:
|
|||||||
name: enabled
|
name: enabled
|
||||||
schema:
|
schema:
|
||||||
type: boolean
|
type: boolean
|
||||||
- in: query
|
|
||||||
name: enrollment_flow
|
|
||||||
schema:
|
|
||||||
type: string
|
|
||||||
format: uuid
|
|
||||||
- in: query
|
- in: query
|
||||||
name: group_membership_field
|
name: group_membership_field
|
||||||
schema:
|
schema:
|
||||||
@ -12115,12 +12105,10 @@ paths:
|
|||||||
schema:
|
schema:
|
||||||
type: integer
|
type: integer
|
||||||
- in: query
|
- in: query
|
||||||
name: policy_engine_mode
|
name: peer_certificate
|
||||||
schema:
|
schema:
|
||||||
type: string
|
type: string
|
||||||
enum:
|
format: uuid
|
||||||
- all
|
|
||||||
- any
|
|
||||||
- in: query
|
- in: query
|
||||||
name: property_mappings
|
name: property_mappings
|
||||||
schema:
|
schema:
|
||||||
@ -22461,6 +22449,12 @@ components:
|
|||||||
server_uri:
|
server_uri:
|
||||||
type: string
|
type: string
|
||||||
format: uri
|
format: uri
|
||||||
|
peer_certificate:
|
||||||
|
type: string
|
||||||
|
format: uuid
|
||||||
|
nullable: true
|
||||||
|
description: Optionally verify the LDAP Server's Certificate against the
|
||||||
|
CA Chain in this keypair.
|
||||||
bind_cn:
|
bind_cn:
|
||||||
type: string
|
type: string
|
||||||
start_tls:
|
start_tls:
|
||||||
@ -22558,6 +22552,12 @@ components:
|
|||||||
type: string
|
type: string
|
||||||
minLength: 1
|
minLength: 1
|
||||||
format: uri
|
format: uri
|
||||||
|
peer_certificate:
|
||||||
|
type: string
|
||||||
|
format: uuid
|
||||||
|
nullable: true
|
||||||
|
description: Optionally verify the LDAP Server's Certificate against the
|
||||||
|
CA Chain in this keypair.
|
||||||
bind_cn:
|
bind_cn:
|
||||||
type: string
|
type: string
|
||||||
bind_password:
|
bind_password:
|
||||||
@ -27181,6 +27181,12 @@ components:
|
|||||||
type: string
|
type: string
|
||||||
minLength: 1
|
minLength: 1
|
||||||
format: uri
|
format: uri
|
||||||
|
peer_certificate:
|
||||||
|
type: string
|
||||||
|
format: uuid
|
||||||
|
nullable: true
|
||||||
|
description: Optionally verify the LDAP Server's Certificate against the
|
||||||
|
CA Chain in this keypair.
|
||||||
bind_cn:
|
bind_cn:
|
||||||
type: string
|
type: string
|
||||||
bind_password:
|
bind_password:
|
||||||
|
|||||||
@ -2608,6 +2608,7 @@ msgstr "Loading"
|
|||||||
#: src/pages/sources/ldap/LDAPSourceForm.ts
|
#: src/pages/sources/ldap/LDAPSourceForm.ts
|
||||||
#: src/pages/sources/ldap/LDAPSourceForm.ts
|
#: src/pages/sources/ldap/LDAPSourceForm.ts
|
||||||
#: src/pages/sources/ldap/LDAPSourceForm.ts
|
#: src/pages/sources/ldap/LDAPSourceForm.ts
|
||||||
|
#: src/pages/sources/ldap/LDAPSourceForm.ts
|
||||||
#: src/pages/sources/oauth/OAuthSourceForm.ts
|
#: src/pages/sources/oauth/OAuthSourceForm.ts
|
||||||
#: src/pages/sources/oauth/OAuthSourceForm.ts
|
#: src/pages/sources/oauth/OAuthSourceForm.ts
|
||||||
#: src/pages/sources/plex/PlexSourceForm.ts
|
#: src/pages/sources/plex/PlexSourceForm.ts
|
||||||
@ -4743,6 +4744,7 @@ msgstr "TLS Authentication Certificate"
|
|||||||
#~ msgstr "TLS Server name"
|
#~ msgstr "TLS Server name"
|
||||||
|
|
||||||
#: src/pages/outposts/ServiceConnectionDockerForm.ts
|
#: src/pages/outposts/ServiceConnectionDockerForm.ts
|
||||||
|
#: src/pages/sources/ldap/LDAPSourceForm.ts
|
||||||
msgid "TLS Verification Certificate"
|
msgid "TLS Verification Certificate"
|
||||||
msgstr "TLS Verification Certificate"
|
msgstr "TLS Verification Certificate"
|
||||||
|
|
||||||
@ -5651,6 +5653,10 @@ msgstr "When a user returns from the email successfully, their account will be a
|
|||||||
msgid "When a valid username/email has been entered, and this option is enabled, the user's username and avatar will be shown. Otherwise, the text that the user entered will be shown."
|
msgid "When a valid username/email has been entered, and this option is enabled, the user's username and avatar will be shown. Otherwise, the text that the user entered will be shown."
|
||||||
msgstr "When a valid username/email has been entered, and this option is enabled, the user's username and avatar will be shown. Otherwise, the text that the user entered will be shown."
|
msgstr "When a valid username/email has been entered, and this option is enabled, the user's username and avatar will be shown. Otherwise, the text that the user entered will be shown."
|
||||||
|
|
||||||
|
#: src/pages/sources/ldap/LDAPSourceForm.ts
|
||||||
|
msgid "When connecting to an LDAP Server with TLS, certificates are not checked by default. Specify a keypair to validate the remote certificate."
|
||||||
|
msgstr "When connecting to an LDAP Server with TLS, certificates are not checked by default. Specify a keypair to validate the remote certificate."
|
||||||
|
|
||||||
#: src/pages/stages/email/EmailStageForm.ts
|
#: src/pages/stages/email/EmailStageForm.ts
|
||||||
msgid "When enabled, global Email connection settings will be used and connection settings below will be ignored."
|
msgid "When enabled, global Email connection settings will be used and connection settings below will be ignored."
|
||||||
msgstr "When enabled, global Email connection settings will be used and connection settings below will be ignored."
|
msgstr "When enabled, global Email connection settings will be used and connection settings below will be ignored."
|
||||||
|
|||||||
@ -2589,6 +2589,7 @@ msgstr "Chargement en cours"
|
|||||||
#: src/pages/sources/ldap/LDAPSourceForm.ts
|
#: src/pages/sources/ldap/LDAPSourceForm.ts
|
||||||
#: src/pages/sources/ldap/LDAPSourceForm.ts
|
#: src/pages/sources/ldap/LDAPSourceForm.ts
|
||||||
#: src/pages/sources/ldap/LDAPSourceForm.ts
|
#: src/pages/sources/ldap/LDAPSourceForm.ts
|
||||||
|
#: src/pages/sources/ldap/LDAPSourceForm.ts
|
||||||
#: src/pages/sources/oauth/OAuthSourceForm.ts
|
#: src/pages/sources/oauth/OAuthSourceForm.ts
|
||||||
#: src/pages/sources/oauth/OAuthSourceForm.ts
|
#: src/pages/sources/oauth/OAuthSourceForm.ts
|
||||||
#: src/pages/sources/plex/PlexSourceForm.ts
|
#: src/pages/sources/plex/PlexSourceForm.ts
|
||||||
@ -4699,6 +4700,7 @@ msgstr "Certificat TLS d'authentification"
|
|||||||
#~ msgstr "Nom TLS du serveur"
|
#~ msgstr "Nom TLS du serveur"
|
||||||
|
|
||||||
#: src/pages/outposts/ServiceConnectionDockerForm.ts
|
#: src/pages/outposts/ServiceConnectionDockerForm.ts
|
||||||
|
#: src/pages/sources/ldap/LDAPSourceForm.ts
|
||||||
msgid "TLS Verification Certificate"
|
msgid "TLS Verification Certificate"
|
||||||
msgstr "Certificat de vérification TLS"
|
msgstr "Certificat de vérification TLS"
|
||||||
|
|
||||||
@ -5594,6 +5596,10 @@ msgstr "Lorsqu'un utilisateur revient de l'e-mail avec succès, son compte sera
|
|||||||
msgid "When a valid username/email has been entered, and this option is enabled, the user's username and avatar will be shown. Otherwise, the text that the user entered will be shown."
|
msgid "When a valid username/email has been entered, and this option is enabled, the user's username and avatar will be shown. Otherwise, the text that the user entered will be shown."
|
||||||
msgstr "Lorsqu'un nom d'utilisateur/email valide a été saisi, et si cette option est active, le nom d'utilisateur et l'avatar de l'utilisateur seront affichés. Sinon, le texte que l'utilisateur a saisi sera affiché."
|
msgstr "Lorsqu'un nom d'utilisateur/email valide a été saisi, et si cette option est active, le nom d'utilisateur et l'avatar de l'utilisateur seront affichés. Sinon, le texte que l'utilisateur a saisi sera affiché."
|
||||||
|
|
||||||
|
#: src/pages/sources/ldap/LDAPSourceForm.ts
|
||||||
|
msgid "When connecting to an LDAP Server with TLS, certificates are not checked by default. Specify a keypair to validate the remote certificate."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: src/pages/stages/email/EmailStageForm.ts
|
#: src/pages/stages/email/EmailStageForm.ts
|
||||||
msgid "When enabled, global Email connection settings will be used and connection settings below will be ignored."
|
msgid "When enabled, global Email connection settings will be used and connection settings below will be ignored."
|
||||||
msgstr "Si activé, les paramètres globaux de connexion courriel seront utilisés et les paramètres de connexion ci-dessous seront ignorés."
|
msgstr "Si activé, les paramètres globaux de connexion courriel seront utilisés et les paramètres de connexion ci-dessous seront ignorés."
|
||||||
|
|||||||
@ -2600,6 +2600,7 @@ msgstr ""
|
|||||||
#: src/pages/sources/ldap/LDAPSourceForm.ts
|
#: src/pages/sources/ldap/LDAPSourceForm.ts
|
||||||
#: src/pages/sources/ldap/LDAPSourceForm.ts
|
#: src/pages/sources/ldap/LDAPSourceForm.ts
|
||||||
#: src/pages/sources/ldap/LDAPSourceForm.ts
|
#: src/pages/sources/ldap/LDAPSourceForm.ts
|
||||||
|
#: src/pages/sources/ldap/LDAPSourceForm.ts
|
||||||
#: src/pages/sources/oauth/OAuthSourceForm.ts
|
#: src/pages/sources/oauth/OAuthSourceForm.ts
|
||||||
#: src/pages/sources/oauth/OAuthSourceForm.ts
|
#: src/pages/sources/oauth/OAuthSourceForm.ts
|
||||||
#: src/pages/sources/plex/PlexSourceForm.ts
|
#: src/pages/sources/plex/PlexSourceForm.ts
|
||||||
@ -4735,6 +4736,7 @@ msgstr ""
|
|||||||
#~ msgstr ""
|
#~ msgstr ""
|
||||||
|
|
||||||
#: src/pages/outposts/ServiceConnectionDockerForm.ts
|
#: src/pages/outposts/ServiceConnectionDockerForm.ts
|
||||||
|
#: src/pages/sources/ldap/LDAPSourceForm.ts
|
||||||
msgid "TLS Verification Certificate"
|
msgid "TLS Verification Certificate"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
@ -5636,6 +5638,10 @@ msgstr ""
|
|||||||
msgid "When a valid username/email has been entered, and this option is enabled, the user's username and avatar will be shown. Otherwise, the text that the user entered will be shown."
|
msgid "When a valid username/email has been entered, and this option is enabled, the user's username and avatar will be shown. Otherwise, the text that the user entered will be shown."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/pages/sources/ldap/LDAPSourceForm.ts
|
||||||
|
msgid "When connecting to an LDAP Server with TLS, certificates are not checked by default. Specify a keypair to validate the remote certificate."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: src/pages/stages/email/EmailStageForm.ts
|
#: src/pages/stages/email/EmailStageForm.ts
|
||||||
msgid "When enabled, global Email connection settings will be used and connection settings below will be ignored."
|
msgid "When enabled, global Email connection settings will be used and connection settings below will be ignored."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|||||||
@ -7,6 +7,7 @@ import { until } from "lit/directives/until.js";
|
|||||||
|
|
||||||
import {
|
import {
|
||||||
CoreApi,
|
CoreApi,
|
||||||
|
CryptoApi,
|
||||||
LDAPSource,
|
LDAPSource,
|
||||||
LDAPSourceRequest,
|
LDAPSourceRequest,
|
||||||
PropertymappingsApi,
|
PropertymappingsApi,
|
||||||
@ -141,6 +142,44 @@ export class LDAPSourceForm extends ModelForm<LDAPSource, string> {
|
|||||||
${t`To use SSL instead, use 'ldaps://' and disable this option.`}
|
${t`To use SSL instead, use 'ldaps://' and disable this option.`}
|
||||||
</p>
|
</p>
|
||||||
</ak-form-element-horizontal>
|
</ak-form-element-horizontal>
|
||||||
|
<ak-form-element-horizontal
|
||||||
|
label=${t`TLS Verification Certificate`}
|
||||||
|
name="peerCertificate"
|
||||||
|
>
|
||||||
|
<select class="pf-c-form-control">
|
||||||
|
<option
|
||||||
|
value=""
|
||||||
|
?selected=${this.instance?.peerCertificate === undefined}
|
||||||
|
>
|
||||||
|
---------
|
||||||
|
</option>
|
||||||
|
${until(
|
||||||
|
new CryptoApi(DEFAULT_CONFIG)
|
||||||
|
.cryptoCertificatekeypairsList({
|
||||||
|
ordering: "name",
|
||||||
|
})
|
||||||
|
.then((keys) => {
|
||||||
|
return keys.results.map((key) => {
|
||||||
|
let selected =
|
||||||
|
this.instance?.peerCertificate === key.pk;
|
||||||
|
if (keys.results.length === 1) {
|
||||||
|
selected = true;
|
||||||
|
}
|
||||||
|
return html`<option
|
||||||
|
value=${ifDefined(key.pk)}
|
||||||
|
?selected=${selected}
|
||||||
|
>
|
||||||
|
${key.name}
|
||||||
|
</option>`;
|
||||||
|
});
|
||||||
|
}),
|
||||||
|
html`<option>${t`Loading...`}</option>`,
|
||||||
|
)}
|
||||||
|
</select>
|
||||||
|
<p class="pf-c-form__helper-text">
|
||||||
|
${t`When connecting to an LDAP Server with TLS, certificates are not checked by default. Specify a keypair to validate the remote certificate.`}
|
||||||
|
</p>
|
||||||
|
</ak-form-element-horizontal>
|
||||||
<ak-form-element-horizontal label=${t`Bind CN`} name="bindCn">
|
<ak-form-element-horizontal label=${t`Bind CN`} name="bindCn">
|
||||||
<input
|
<input
|
||||||
type="text"
|
type="text"
|
||||||
|
|||||||
Reference in New Issue
Block a user