LDAP-Einstellungen
From LimeSurvey Manual
Generelles
Um diese Funktion nutzen zu können, müssen Sie die LDAP-Unterstützung in config.php aktivieren und LDAP-Parameter in config/ldap.php konfigurieren.
LDAP in config.php aktivieren
- $enableLdap: Wenn Sie LDAP-Funktionen in LimeSurvey verwenden möchten, müssen Sie diesen Parameter auf true setzen (standardmäßig ist er auf false gesetzt):
'config'=>array( 'debug'=>0, 'debugsql'=>0, 'enableLdap'=>true, )
LDAP-Server definieren
Definieren Sie zunächst die LDAP-Server-Verbindungsoptionen in „application/config/ldap.php“. Für jeden Server stehen folgende Optionen zur Verfügung:
- $serverId: Eine Ganzzahl, die diesen LDAP-Server identifiziert. Sie wird in Abfragedefinitionen verwendet, um einen Server an eine bestimmte Abfrage zu binden;
- $ldap_server [ $serverId] [ 'server']: Die IP-Adresse oder der DNS-Name des LDAP-Servers. Bei Verwendung von SSL-gesicherten Verbindungen (LDAPs oder LDAP+Start-TLS) muss dieser Name dem Zertifikats-CN (oder SubjectAlternativeName) des Servers entsprechen;
- $ldap_server [ $serverId] [ 'port']: Der TCP-Port, an dem der LDAP-Server lauscht. Dies ist üblicherweise 389 für LDAP und LDAP+Start-TLS und 636 für LDAPs;
- $ldap_server [ $serverId] [ 'protoversion']: Kann je nach dem von Ihrem Server unterstützten Protokoll 'ldapv2' oder 'ldapv3' sein. 'ldapv3' ist das bevorzugte Protokoll. Wenn Sie jedoch verschlüsselte Verbindungen verwenden möchten, beachten Sie, dass LDAPS im 'ldapv2'-Modus unterstützt wird, während Start-TLS die Verschlüsselungsmethode für 'ldapv3' ist;
- $ldap_server [ $serverId] [ 'encrypt']: Definiert die verwendete Verschlüsselungsmethode. 'ldaps' wird für 'ldapv2'-Server, 'start-tls' für 'ldapv3'-Server unterstützt. Das Schlüsselwort 'none' wird für unverschlüsselte LDAP-Kommunikation verwendet. Vergessen Sie nicht, dass der Webserver bei der Verschlüsselung mit 'ldaps' oder 'start-tls' das Zertifikat des LDAP-Servers überprüfen können muss. Daher müssen Sie Ihre Zertifizierungsstelle in Ihrer OpenLDAP-Bibliothek definieren (normalerweise in der Datei /etc/openldap/ldap.conf unter Linux). $ldap_server [ $serverId] [ 'referrals']: Es handelt sich um einen booleschen Parameter, der festlegt, ob Empfehlungen befolgt werden müssen oder nicht (verwenden Sie false für Active Directory);
- $ldap_server [ $serverId] [ 'encoding']: Dies ist ein optionaler Parameter, der die vom LDAP-Verzeichnis verwendete Kodierung für die Speicherung von Zeichenketten angibt. Normalerweise ist die Konfiguration dieses Parameters nicht erforderlich, da die standardmäßig angenommene Kodierung 'utf-8' die Standardkodierung für LDAP-Verzeichnisse ist. Wenn Sie jedoch Active Directory verwenden und Probleme beim Importieren von Zeichenketten mit Akzenten haben, versuchen Sie, diesen Parameter auf die in Ihrer Region verwendete Kodierung einzustellen (z. B. 'cp850' für Westeuropa). Eine vollständige Liste der unterstützten Kodierungen finden Sie in der Dropdown-Liste „Zeichensatz der Datei“ in der Benutzeroberfläche von Token aus CSV-Datei importieren.
Als Nächstes müssen Sie definieren, welche Authentifizierung erforderlich ist, um Zugriff auf das Verzeichnis zu erhalten. Wenn „anonymer“ Zugriff erlaubt ist, legen Sie die beiden folgenden Parameter NICHT fest, andernfalls legen Sie sie entsprechend fest:
- $ldap_server[$serverId]['binddn']: DN des 'LDAP'-Benutzers, der das Verzeichnis lesen darf;
- $ldap_server[$serverId]['bindpw']: Passwort für den oben genannten LDAP-Benutzer.
Wenn Sie andere LDAP-Server definieren müssen, fügen Sie die folgende Zeile hinzu, um die Server-ID zu erhöhen und neue Parameter zu definieren:
- $serverId++.
Definieren von Abfragen in config/ldap.php
Achtung: Wenn in einem dieser Parameter ein „LDAP-Attributname“ erforderlich ist, „verwenden Sie nur Namen in Kleinbuchstaben“, zum Beispiel „displayname“ und NICHT „displayName“.
Bitte beachten Sie die Datei config/ldap.php, da sie Beispielkonfigurationen enthält.
Einfache Abfragen
Beginnen wir mit einfachen Abfragen. Diese Abfragen filtern LDAP-Einträge nur basierend auf ihren eigenen Attributen und ihrem Standort. Sie reichen normalerweise aus, um ActiveDirectory abzufragen.
- $query_id: Ist die ID der LDAP-Abfrage;
- $ldap_queries[$query_id]['ldapServerId']: Bindet die Abfrage an einen bestimmten Server;
- $ldap_queries[$query_id]['name']: String, der die Abfrage beschreibt. Es wird in der GUI angezeigt;
- $ldap_queries[$query_id]['userbase']: Root-DN zur Verwendung für Benutzersuchen;
- $ldap_queries[$query_id] ['userfilter']: Dies ist ein Filter, der zur Auswahl potenzieller Benutzereinträge verwendet wird. Es muss in Klammern eingeschlossen werden;
- $ldap_queries[$query_id]['userscope']: Umfang der LDAP-Suche nach Benutzern ('base', 'one' oder 'sub');
- $ldap_queries[$query_id]['firstname_attr']: Ldap-Attribut, das dem Firstname-Feld des Token-Eintrags zugeordnet wird;
- $ldap_queries[$query_id]['lastname_attr']: Ldap-Attribut, das dem Feld Nachname des Token-Eintrags zugeordnet wird;
- $ldap_queries[$query_id]['email_attr']: Ldap-Attribut, das dem E-Mail-Adressfeld des Token-Eintrags zugeordnet wird.
Optional können Sie weitere Informationen aus dem Verzeichnis abrufen:
- $ldap_queries[$query_id]['token_attr']: Ldap-Attribut, das dem Token-Code zugeordnet wird;
- $ldap_queries[$query_id]['Sprache']: Ldap-Attribut, das dem Benutzersprachencode zugeordnet wird;
- $ldap_queries[$query_id]['attr1']: Ldap-Attribut, das dem Feld attribute_1 zugeordnet wird;
- $ldap_queries[$query_id]['attr2']: Ldap-Attribut, das dem Feld attribute_2 zugeordnet wird.
Kombinierte Gruppenabfragen mit DN-Mitgliedern
Sehen wir uns nun an, wie eine kompliziertere Abfrage definiert wird.
Die folgenden Abfragen verwenden eine erste LDAP-Suche, die in LDAP-Gruppen sucht. Eine LDAP-Gruppe ist ein LDAP-Eintrag, der Verweise auf Benutzereinträge in der Form enthält:
- Benutzer-IDs (z. B. posixGroups) ==> siehe nächster Abschnitt
- Oder Benutzer-DNs (z. B. groupofnames und groupofuniquenames) ==> siehe unten
Hier beschäftigen wir uns mit Gruppen, die Benutzer-DNs enthalten:
- definiere $query_id, $ldap_queries[$query_id]['ldapServerId'], $ldap_queries[$query_id]['Name'] wie oben erläutert.
Definieren Sie dann die Gruppenfilterparameter:
- $ldap_queries[$query_id]['groupbase']: Der Root-DN, von dem aus Sie mit der Suche nach Gruppeneinträgen beginnen möchten;
- $ldap_queries[$query_id]['groupfilter']: Der LDAP-Filter, der potenzielle Gruppeneinträge auswählt;
- $ldap_queries[$query_id]['groupscope']: Der Bereich der LDAP-Suche nach Gruppen ('one', 'base' oder 'sub');
- $ldap_queries[$query_id]['groupmemberattr']: Der Name des LDAP-Attributs im Gruppeneintrag, der Verweise auf Benutzereinträge enthält;
- $ldap_queries[$query_id]['groupmemberisdn']: TRUE.
Zu diesem Zeitpunkt ist alles so eingerichtet, dass die erste LDAP-Suche Benutzer findet, die den ausgewählten Gruppen entsprechen. Sie können jedoch einschränken, welche dieser „Benutzerkandidaten“ ausgewählt werden, indem Sie einen anderen Filter auf sie anwenden. Dies ist natürlich optional:
- $ldap_queries[$query_id]['userbase']: Basis-DN für die Benutzer-LDAP-Suche (nur Benutzerkandidaten, die dieser Basis entsprechen) wird ausgewählt;
- $ldap_queries[$query_id]['userscope']: Bereich für die Benutzer-LDAP-Suche (nur Benutzerkandidaten, die der Benutzerbasis+Bereich entsprechen) wird ausgewählt;
- $ldap_queries[$query_id]['userfilter']: Es handelt sich um einen Filter, der auf jeden Benutzerkandidateneintrag (auf seine Attribute) angewendet wird, um eine weitere Auswahl hinzuzufügen.
Kombinierte Gruppenabfragen mit UID-Mitgliedern
Sehen wir uns nun an, wie eine kombinierte Gruppenabfrage definiert wird, wenn Gruppenmitglieder Benutzer-UIDs und keine Benutzer-DNs sind.
Was die Gruppenabfragen mit DNs-Mitgliedern betrifft, verwenden diese Abfragen eine erste LDAP-Suche, die nach LDAP-Gruppeneinträgen sucht und deren Mitglieder abruft. Diese Mitgliedswerte werden dann in einem Benutzersuchfilter verwendet, um nach entsprechenden Einträgen zu suchen. Daher muss ein weiterer Parameter konfiguriert werden, um das Benutzerattribut im Benutzereintrag zu definieren, das mit der in den Gruppen gefundenen Mitglieds-UID übereinstimmen soll.
Sehen wir uns die erforderlichen Parameter an:
- definiere $query_id, $ldap_queries[$query_id]['ldapServerId'], $ldap_queries[$query_id]['Name'] wie oben erläutert
Definieren Sie dann die Gruppenfilterparameter:
- $ldap_queries[$query_id]['groupbase']: Der Root-DN, von dem aus Sie mit der Suche nach Gruppeneinträgen beginnen möchten;
- $ldap_queries[$query_id]['groupfilter']: Der LDAP-Filter, der potenzielle Gruppeneinträge auswählt;
- $ldap_queries[$query_id]['groupscope']: Der Bereich der LDAP-Suche nach Gruppen ('one', 'base' oder 'sub');
- $ldap_queries[$query_id]['groupmemberattr']: Der Name des LDAP-Attributs im Gruppeneintrag, der Verweise auf Benutzereinträge enthält;
- $ldap_queries[$query_id]['groupmemberisdn']: FALSE;
- $ldap_queries[$query_id]['useridattr']: Name des Benutzerattributs, das mit der in den Gruppenmitgliedern gefundenen UID übereinstimmen muss.
An diesem Punkt ist alles so eingerichtet, dass die erste LDAP-Suche Benutzer-UIDs findet, die den ausgewählten Gruppen entsprechen, und ein Benutzersuchfilter wird automatisch ausgefüllt.
Sie können jedoch einschränken, welche dieser „Benutzerkandidaten“ ausgewählt werden, indem Sie den automatischen Benutzerfilter ausfüllen, der aus den UIDs der Mitglieder berechnet wird. Dies ist natürlich optional:
- $ldap_queries[$query_id]['userbase']: Basis-DN für die Benutzer-LDAP-Suche (nur Benutzerkandidaten, die dieser Basis entsprechen) wird ausgewählt;
- $ldap_queries[$query_id]['userscope']: Bereich für die Benutzer-LDAP-Suche (nur Benutzerkandidaten, die der Benutzerbasis+Bereich entsprechen) wird ausgewählt;
- $ldap_queries[$query_id]['userfilter']: Es handelt sich um einen Filter, der auf jeden Benutzerkandidateneintrag (auf seine Attribute) angewendet wird, um eine weitere Auswahl hinzuzufügen.
Was ist mit Active Directory?
Active Directory (AD) ist eine Microsoft-Registrierung, die mithilfe des LDAP-Protokolls abgefragt werden kann.
Es ist dann möglich, seinen Inhalt für LimeSurvey-Token-Abfragen zu verwenden, aber dies erfordert Kenntnisse darüber, wie AD organisiert ist.
- Die LDAP-Stammbasis ist dc=my_windows_domain_name,dc=dns_suffix2,dc=dns_suffix1
==> Wenn Ihr Unternehmen beispielsweise die DNS-Domäne "meine-firma.com" besitzt und Ihre Windows-Domäne "Mitarbeiter" ist, dann lautet Ihre Stammdatenbasis dc=Mitarbeiter,dc=meine-firma,dc=com
- Benutzer und Benutzergruppen werden unter cn=Users,dc=my_windows_domain_name,dc=dns_suffix2,dc=dns_suffix1 gespeichert (bitte beachten Sie, dass dies nicht ou=users ist);
- Active Directory Gruppen:
- Gruppenobjekte enthalten den DN der Mitglieder in ihrem Attribut "member";
- Gruppenmitgliedschaften werden auch im memberOf-Attribut eines jeden Benutzereintrags gespeichert. Dieses Attribut enthält die DNs der Gruppen, denen der Benutzer angehört;
- Einige Gruppen befinden sich in CN=Builtin,dc=my_windows_domain_name,dc=dns_suffix2,dc=dns_suffix1:
- Zum Beispiel: cn=Administrator,CN=Builtin,dc=my_windows_domain_name,dc=dns_suffix2,dc=dns_suffix1;
In manchen Fällen ist es nicht so einfach, ein Active Directory abzufragen. Daher hier eine Beispielkonfiguration zum Abrufen von Informationen aus einem Active Directory:
//Verbindung zum Active Directory-Server:
$serverId=0;
$ldap_server[$serverId]['server'] = "10.10.10.10";
$ldap_server[$serverId]['port'] = "389";
$ldap_server[$serverId]['protoversion'] = "ldapv2";
$ldap_server[$serverId]['encrypt'] = "none"; // Die meisten AD LDAP-Server haben standardmäßig keine Verschlüsselung
$ldap_server[$serverId]['referrals'] = false;
$ldap_server[$serverId]['binddn'] = "domain\\user";
$ldap_server[$serverId]['bindpw'] = "userpassword";
//$ldap_server[$serverId]['binddn'] = "CN=user,OU=user_group,DC=xxx,DC=yyy"; Diese Abfrage funktioniert nicht mit Active Directory, daher müssen Sie "Domäne\Benutzer" verwenden
//Hier ist eine Beispielabfrage zum Abrufen aller aktiven Benutzer eines Active Directory:
$query_id=0;
$ldap_queries[$query_id]['ldapServerId'] = 0;
$ldap_queries[$query_id]['name'] = 'Mitarbeiter mit aktiviertem Konto';
$ldap_queries[$query_id]['userbase'] = 'OU=USER_GROUP,DC=xxx,DC=yyy';
$ldap_queries[$query_id]['userfilter'] = '(&(objectClass=user)(!(userAccountControl:1.2.840.113556.1.4.803:=2)))';
//AD hat kein Attribut "Konto ist aktiviert", Der Filter schließt also Konten aus, bei denen das Flag "deaktiviert" (Bit 2) in userAccountControl gesetzt ist
$ldap_queries[$query_id]['userscope'] = 'sub';
$ldap_queries[$query_id]['firstname_attr'] = 'givenname';
$ldap_queries[$query_id]['lastname_attr'] = 'sn';
$ldap_queries[$query_id]['email_attr'] = 'mail';
$ldap_queries[$query_id]['token_attr'] = ''; // Für die automatische Token-Generierung durch phpsv leer lassen
$ldap_queries[$query_id]['language'] = '';
$ldap_queries[$query_id]['attr1'] = '';
$ldap_queries[$query_id]['attr2'] = '';
//Sie können auch nach Gruppenzugehörigkeit über das memberOf-Attribut des Benutzers filtern. Hier ist eine Beispielabfrage, um alle aktiven Benutzer der Gruppe „samplegroup“ in Active Directory abzurufen:
$query_id++;
$ldap_queries[$query_id]['ldapServerId'] = 0;
$ldap_queries[$query_id]['name'] = 'Alle Mitglieder von samplegroup';
$ldap_queries[$query_id]['userbase'] = 'OU=USER_GROUP,DC=xxx,DC=yyy';
$ldap_queries[$query_id]['userfilter'] = '(&(objectClass=user)(memberOf=CN=samplegroup,OU=Group Global,OU=USER_GROUP,DC=xxx,DC=yyy)(!(userAccountControl:1.2.840.113556.1.4.803:=2)))';
$ldap_queries[$query_id]['userscope'] = 'sub';
$ldap_queries[$query_id]['firstname_attr'] = 'givenname';
$ldap_queries[$query_id]['lastname_attr'] = 'sn';
$ldap_queries[$query_id]['email_attr'] = 'mail';
$ldap_queries[$query_id]['token_attr'] = ''; // Für die automatische Token-Generierung durch phpsv leer lassen
$ldap_queries[$query_id]['language'] = '';
$ldap_queries[$query_id]['attr1'] = '';
$ldap_queries[$query_id]['attr2'] = '';
Ein weiteres Beispiel: Benutzerabfrage:
$ldap_queries[$query_id]['userfilter'] = '(&(objectCategory=Person)(objectClass=user)(!(userAccountControl:1.2.840.113556.1.4.803:=2)))'; // AD erkennt aktivierte Konten nicht auf die übliche Weise, daher prüfen wir stattdessen, ob die Benutzer deaktiviert sind
- Erwägen Sie, (mail=*) zu Ihren Benutzerfiltern hinzuzufügen, um Benutzer ohne E-Mail-Adresse zu überspringen.
Beispiel für eine Gruppenabfrage:
$ldap_queries[$query_id]['groupfilter'] = '(&(objectClass=group)(cn=Domain Admins))'; // AD verwendet nicht den Standardattributnamen für Gruppen, daher verwenden Sie stattdessen dieses Beispiel.
Automatische Erstellung einer Abfrage pro Active Directory-Gruppe
Wenn Sie die Gruppen Ihrer Umfrageteilnehmer in einer Organisationseinheit (OU) zusammenfassen, müssen Sie nicht für jede Gruppe eine separate Abfrage erstellen. Der folgende Code listet alle Gruppen in dieser OU auf und erstellt für jede Gruppe eine separate Abfrage. Die Abfrage umfasst alle aktivierten Mitglieder der Gruppe, einschließlich der Mitglieder verschachtelter Gruppen.
Fügen Sie den Code in die Datei `config/ldap.php` nach Ihren Server- und Abfragedefinitionen und vor der Zeile //DO NOT CHANGE BELOW HERE ein. Legen Sie anschließend die vier Variablen oben fest: `
- $groupServerId: die Server-ID des zu verwendenden Servers;
- $groupContainer: den DN der Organisationseinheit (OU), die die Gruppen enthält. Es werden nur Gruppen direkt in dieser OU aufgelistet, nicht Gruppen in Unter-OUs;
- $groupUserBase: den Stamm-DN, unter dem die Gruppenmitglieder gesucht werden;
- $groupNameAttr: das Gruppenattribut (in Kleinbuchstaben), das als Abfragename in der GUI verwendet wird, z. B. 'info' (das Feld „Notizen“ in „Active Directory-Benutzer und -Computer“) oder 'description'. Wenn eine Gruppe keinen Wert in diesem Attribut hat, wird ihr CN verwendet.
$groupServerId = 0;
$groupContainer = 'OU=Survey groups,DC=xxx,DC=yyy';
$groupUserBase = 'DC=xxx,DC=yyy';
$groupNameAttr = 'info';
$srv = $ldap_server[$groupServerId];
$ds = ldap_connect(($srv['encrypt'] == 'ldaps' ? 'ldaps://' : 'ldap://') . $srv['server'] . ':' . $srv['port']);
if ($ds) {
ldap_set_option($ds, LDAP_OPT_PROTOCOL_VERSION, $srv['protoversion'] == 'ldapv3' ? 3 : 2);
ldap_set_option($ds, LDAP_OPT_REFERRALS, 0);
// Niemals das Bind-Passwort senden, wenn Start-TLS angefordert wurde, aber fehlgeschlagen ist
$secure = $srv['encrypt'] != 'start-tls' || @ldap_start_tls($ds);
$bound = $secure && (empty($srv['binddn']) ? @ldap_bind($ds) : @ldap_bind($ds, $srv['binddn'], $srv['bindpw']));
$result = $bound ? @ldap_list($ds, $groupContainer, '(objectCategory=group)', array('cn', $groupNameAttr)) : false;
$groups = $result ? ldap_get_entries($ds, $result) : array('count' => 0);
for ($i = 0; $i < $groups['count']; $i++) {
$query_id++;
$ldap_queries[$query_id]['ldapServerId'] = $groupServerId;
$ldap_queries[$query_id]['name'] = isset($groups[$i][$groupNameAttr][0]) ? $groups[$i][$groupNameAttr][0] : $groups[$i]['cn'][0];
$ldap_queries[$query_id]['userbase'] = $groupUserBase;
// Aktivierte Benutzer mit einer E-Mail-Adresse, die Mitglieder der Gruppe sind, direkt oder über verschachtelte Gruppen
$ldap_queries[$query_id]['userfilter'] = '(&(objectCategory=person)(objectClass=user)(mail=*)'
. '(!(userAccountControl:1.2.840.113556.1.4.803:=2))'
. '(memberOf:1.2.840.113556.1.4.1941:=' . ldap_escape($groups[$i]['dn'], '', LDAP_ESCAPE_FILTER) . '))';
$ldap_queries[$query_id]['userscope'] = 'sub';
$ldap_queries[$query_id]['firstname_attr'] = 'givenname';
$ldap_queries[$query_id]['lastname_attr'] = 'sn';
$ldap_queries[$query_id]['email_attr'] = 'mail';
$ldap_queries[$query_id]['token_attr'] = '';
$ldap_queries[$query_id]['language'] = '';
$ldap_queries[$query_id]['attr1'] = '';
$ldap_queries[$query_id]['attr2'] = '';
}
ldap_unbind($ds);
}
Wichtige Hinweise: * Der Code stellt jedes Mal eine Verbindung zum Verzeichnis her, wenn die Seite „Teilnehmer aus LDAP importieren“ geöffnet oder abgeschickt wird. Dadurch werden neue Gruppen angezeigt, ohne dass die Konfiguration geändert werden muss. Bei einem Verbindungs- oder Bindungsfehler werden nur die manuell definierten Abfragen angezeigt.
- Die Matching-Regel 1.2.840.113556.1.4.1941 (LDAP_MATCHING_RULE_IN_CHAIN) löst verschachtelte Gruppen auf. Sie existiert nur in Active Directory. Dieses Beispiel funktioniert daher nicht mit anderen LDAP-Servern. Verwenden Sie stattdessen für jede Gruppe eine kombinierte Gruppenabfrage (combined group query).
- Um auch Gruppen in Unter-OUs von $groupContainer aufzulisten, ersetzen Sie ldap_list durch ldap_search.
- Um Gruppen aus mehreren OUs aufzulisten, wiederholen Sie den Code mit anderen Werten für die vier Variablen.
Weitere Informationen zur Active Directory LDAP-Struktur finden Sie unter Active Directory Architecture und [1] (Bibliothek/cc223122.aspx Technische Spezifikation für Active Directory).