6.9.7. Autorisation et Chargement de groupes avec LDAP

Un annuaire LDAP contient des entrées pour les comptes d'utilisateurs et de groupes, dont les références sont mises en correspondance par des attributs. Selon la configuration du serveur LDAP, une entité utilisatrice peut mapper les groupes à qui appartient l'utilisateur via les attributs memberOf ; une entité du groupe peut mapper les utilisateurs lui appartenant par les attributs uniqueMember ; ou les deux mappages peuvent être maintenus dans le serveur LDAP.
Il est également fréquent qu'un utilisateur soit authentifié auprès du serveur à l'aide d'un simple nom utilisateur. Pour les recherches d'informations d'appartenance de groupe selon le serveur de répertoires utilisé, les recherches d'utilisation peuvent être effectuées à l'aide de ce simple nom ou peuvent être réalisées en utilisant le nom unique d'entrée utilisateur du répertoire.
L'étape d'authentification d'un utilisateur qui se connecte au serveur a toujours lieu en premier. Une fois que l'utilisateur a bien été authentifié, le serveur charge un groupe d'utilisateurs. L'étape d'authentification et d'autorisation utilisent chacune une connexion au serveur LDAP. Le domaine contient une optimisation qui consiste à utiliser la connexion utilisée pour l'étape de chargement de groupe. Tel qu'il apparaît dans les étapes de configuration ci-dessous, il est possible de définir des règles au sein de la section autorisation pour convertir un nom d'utilisateur simple en nom unique d'utilisateur. Le résultat de la recherche « nom d'utilisateur à mappage de nom unique » en cours d'authentification est mis en cache et réutilisé lors de la demande d'autorisation quand l'attribut force est défini à «false». Quand force est défini à true, la recherche a lieu à nouveau en cours d'autorisation (pendant le chargement des groupes). Cela est normalement effectué quand des serveurs différents effectuent l'authentification et l'autorisation.
<authorization>
    <ldap connection="...">
    	<!-- OPTIONAL -->
       <username-to-dn force="true"> 
           <!-- Only one of the following. -->
           <username-is-dn />
           <username-filter base-dn="..." recursive="..." user-dn-attribute="..." attribute="..." />
           <advanced-filter base-dn="..." recursive="..." user-dn-attribute="..." filter="..." />
        </username-to-dn>
        
       <group-search group-name="..." iterative="..." group-dn-attribute="..." group-name-attribute="..." >
           <!-- One of the following -->
           <group-to-principal base-dn="..." recursive="..." search-by="...">
               <membership-filter principal-attribute="..." />
           </group-to-principal>
           <principal-to-group group-attribute="..." />
       </group-search>
    </ldap>
</authorization>

Important

Ces exemples indiquent des attributs qui utilisent des valeurs par défaut. Ces valeurs sont indiquées ici pour clarifier. Les attributs qui contiennent les valeurs par défaut sont supprimées de la configuration quand c'est persisté sur le serveur. L'exception est l'attribut force. Il est requis, même quand défini à la valeur par défaut false.

username-to-dn

L'élément username-to-dn indique comment mapper le nom d'utilisateur au nom distinctif de son entrée dans le répertoire LDAP. Cet élément n'est requis que lorsque les deux énoncés suivants sont véréfiées :
  • Les étapes d'authentification et d'autorisation sont effectués sur deux serveurs LDAP distincts.
  • La recherche de groupe utilise un nom distinctif.
1:1 username-to-dn

Ceci indique que le nom d'utilisateur saisi par l'utilisateur distant est le nom distinctif de l'utilisateur.
<username-to-dn force="false">
   <username-is-dn />
</username-to-dn>

Ceci définit un mappage 1:1, et il n'y a pas de configuration supplémentaire possible.
username-filter

La prochaine option est très semblable à la simple option décrite ci-dessus dans l'étape d'authentification. Un attribut est spécifié et on recherche une correspondance avec le nom d'utilisateur fourni.
<username-to-dn force="true">
    <username-filter base-dn="dc=people,dc=harold,dc=example,dc=com" recursive="false" attribute="sn" user-dn-attribute="dn" />
</username-to-dn>

Les attributs pouvant être définis sont les suivants :
  • base-dn : le nom distinctif du contexte pour commencer la recherche.
  • recursive : indique si la recherche va s'étendre à des sous-contextes. La valeur par défaut est false.
  • attribute : l'attribut de l'entrée de l'utilisateur à faire correspondre avec le nom d'utilisateur fourni. La valeur par défaut est uid.
  • user-dn-attribute : l'attribut à lire pour obtenir les noms distinctifs d'utilisateurs. La valeur par défaut est dn.
advanced-filter

L'option finale est de spécifier un filtre avancé. Comme dans la section authentification, c'est l'opportunité d'utiliser un filtre personnalisé pour trouver le nom unique de l'utilisateur.
<username-to-dn force="true">
    <advanced-filter base-dn="dc=people,dc=harold,dc=example,dc=com" recursive="false" filter="sAMAccountName={0}" user-dn-attribute="dn" />
</username-to-dn>

Pour les attributs qui correspondent à ceux du username-filter, le sens et les valeurs par défaut sont les mêmes. Cela laisse un nouvel attribut :
  • filter : filtre personnalisé utilisé pour chercher une entrée d'utilisateur quand le nom d'utilisateur est substitué dans l'espace réservé {0}

Important

Le code XML doit rester valide une fois que le filtre est défini donc si des caractères spéciaux comme & sont utilisés, assurez-vous que la forme qui convient soit utilisée. Par exemple, & amp ; pour le caractère &.

La recherche Groupe

Il existe deux styles différents qui puissent être utilisés lors de la recherche d'informations d'appartenance de groupe. Le premier style est quand l'entrée d'utilisateur contient un attribut qui référence les groupes dont l'utilisateur est membre. Le second style est quand le groupe contient un attribut référençant l'entrée des utilisateurs.

Lorsqu'il y a un choix sur le style à utiliser, Red Hat recommande que la configuration d'entrée utilisateur référençant le groupe soit utilisée. C'est parce qu'avec cette méthode, l'information de groupe peut être chargée par la lecture des attributs des noms uniques connus sans avoir à effectuer les recherches. L'autre approche nécessite des recherches extensives pour identifier les groupes qui référencent l'utilisateur.

Avant de décrire la configuration, voici quelques exemples LDIF pour illustrer cela.

Exemple 6.1. Principal à Groupe - Exemple LDIF

Cet exemple illustre un cas où nous avons un utilisateur TestUserOne, qui est membre de GroupOne, et GroupOne est à son tour membre de GroupFive. L'appartenance au groupe est démontrée par l'utilisation d'un attribut memberOf défini au nom unique du groupe dont l'utilisateur est membre.

Ce n'est pas affiché ici, mais un utilisateur peut avoir plusieurs attributs memberOf définis, un pour chaque groupe dont l'utilisateur est un membre direct.
dn: uid=TestUserOne,ou=users,dc=principal-to-group,dc=example,dc=org
objectClass: extensibleObject
objectClass: top
objectClass: groupMember
objectClass: inetOrgPerson
objectClass: uidObject
objectClass: person
objectClass: organizationalPerson
cn: Test User One
sn: Test User One
uid: TestUserOne
distinguishedName: uid=TestUserOne,ou=users,dc=principal-to-group,dc=example,dc=org
memberOf: uid=GroupOne,ou=groups,dc=principal-to-group,dc=example,dc=org
memberOf: uid=Slashy/Group,ou=groups,dc=principal-to-group,dc=example,dc=org
userPassword:: e1NTSEF9WFpURzhLVjc4WVZBQUJNbEI3Ym96UVAva0RTNlFNWUpLOTdTMUE9PQ==

dn: uid=GroupOne,ou=groups,dc=principal-to-group,dc=example,dc=org
objectClass: extensibleObject
objectClass: top
objectClass: groupMember
objectClass: group
objectClass: uidObject
uid: GroupOne
distinguishedName: uid=GroupOne,ou=groups,dc=principal-to-group,dc=example,dc=org
memberOf: uid=GroupFive,ou=subgroups,ou=groups,dc=principal-to-group,dc=example,dc=org

dn: uid=GroupFive,ou=subgroups,ou=groups,dc=principal-to-group,dc=example,dc=org
objectClass: extensibleObject
objectClass: top
objectClass: groupMember
objectClass: group
objectClass: uidObject
uid: GroupFive
distinguishedName: uid=GroupFive,ou=subgroups,ou=groups,dc=principal-to-group,dc=example,dc=org

Exemple 6.2. Groupe à Principal - Exemple LDIF

Cet exemple montre le même utilisateur TestUserOne qui est un membre de GroupOne, à son tour membre de GroupFive - cependant dans ce cas, c'est un attribut uniqueMember du groupe de l'utilisateur utilisé pour la référence croisée.

Encore une fois, l'attribut utilisé pour la mise en correspondance de l'appartenance à un groupe peut être répété, si vous regardez GroupFive, il y a également une référence à un autre utilisateur TestUserFive non visible ici.
dn: uid=TestUserOne,ou=users,dc=group-to-principal,dc=example,dc=org
objectClass: top
objectClass: inetOrgPerson
objectClass: uidObject
objectClass: person
objectClass: organizationalPerson
cn: Test User One
sn: Test User One
uid: TestUserOne
userPassword:: e1NTSEF9SjR0OTRDR1ltaHc1VVZQOEJvbXhUYjl1dkFVd1lQTmRLSEdzaWc9PQ==

dn: uid=GroupOne,ou=groups,dc=group-to-principal,dc=example,dc=org
objectClass: top
objectClass: groupOfUniqueNames
objectClass: uidObject
cn: Group One
uid: GroupOne
uniqueMember: uid=TestUserOne,ou=users,dc=group-to-principal,dc=example,dc=org

dn: uid=GroupFive,ou=subgroups,ou=groups,dc=group-to-principal,dc=example,dc=org
objectClass: top
objectClass: groupOfUniqueNames
objectClass: uidObject
cn: Group Five
uid: GroupFive
uniqueMember: uid=TestUserFive,ou=users,dc=group-to-principal,dc=example,dc=org
uniqueMember: uid=GroupOne,ou=groups,dc=group-to-principal,dc=example,dc=org

Recherche de groupe standard

Avant de chercher des exemples pour les deux approches montrées ci-dessus, nous devons tout d'abord définir les attributs communs aux deux approches.
<group-search group-name="..." iterative="..." group-dn-attribute="..." group-name-attribute="..." >
    ...
</group-search>
  • group-name : cet attribut est utilisé pour indiquer le formulaire qui doit être utilisé pour le nom de groupe retourné correspondant à la liste de groupes dont l'utilisateur est membre. Cela peut être sous la simple forme de nom du groupe ou de nom unique de groupe. Si le nom unique est nécessaire, cet attribut peut être défini à DISTINGUISHED_NAME. Valeur par défaut SIMPLE.
  • itérative : cet attribut est utilisé pour indiquer si, après avoir identifié les groupes qui appartiennent à un utilisateur, on doit rechercher également de manière itérative basée sur les groupes afin d'identifier quels groupes appartiennent à quels groupes. Si la recherche itérative est activée, nous continuons jusqu'à ce que nous rejoignions un groupe qui ne soit pas membre si aucun autre groupe ou cycle n'est détecté. Par défaut, false.

L'appartenance à un groupe cyclique n'est pas un problème. Il existe un registre de chaque recherche pour empêcher les groupes qui ont déjà été fouillés d'être recherchés à nouveau.

Important

Pour une recherche itérative, les entrées de groupe doivent ressembler aux entrées utilisateur. La même approche qui permet d'identifier les groupes auxquels appartient un utilisateur est alors utilisée pour identifier les groupes auxquels le groupe appartient. Ce ne serait pas possible si, une fois que nous parlons d'appartenance inter groupes, le nom de l'attribut utilisé pour la référence croisée changeait ou si la direction de la référence changeait.
  • group-dn-attribute: sur une entrée pour un groupe dont l'attribut est son nom unique. La valeur par défaut est dn.
  • group-name-attribute: sur une entrée pour un groupe dont l'attribut est son simple nom. La valeur par défaut est uid.

Exemple 6.3. Configuration d'exemple de Principal à Groupe

Basé sur l'exemple LDIF ci-dessus, voici un exemple de configuration chargeant itérativement un groupe d'utilisateurs où l'attribut utilisé pour référence est l'attribut memberOf de l'utilisateur.
<authorization>
    <ldap connection="LocalLdap">
        <username-to-dn>
            <username-filter base-dn="ou=users,dc=principal-to-group,dc=example,dc=org" recursive="false" attribute="uid" user-dn-attribute="dn" />
        </username-to-dn>
        <group-search group-name="SIMPLE" iterative="true" group-dn-attribute="dn" group-name-attribute="uid">
            <principal-to-group group-attribute="memberOf" />
        </group-search>
    </ldap>
</authorization>

L'aspect le plus important de cette configuration est que l'élément principal-to-group a été ajouté avec un seul attribut.
  • group-attribute: le nom de l'attribut sur l'entrée d'utilisateur qui correspond au nom unique du groupe qui appartient à l'utilisateur. La valeur par défaut est memberOf.

Exemple 6.4. Configuration d'exemple de Groupe à Principal

Cet exemple vous montre une recherche interactive pour l'exemple groupe à principal LDIF montré ci-dessus.
<authorization>
      <ldap connection="LocalLdap">
          <username-to-dn>
              <username-filter base-dn="ou=users,dc=group-to-principal,dc=example,dc=org" recursive="false" attribute="uid" user-dn-attribute="dn" />
          </username-to-dn>
          <group-search group-name="SIMPLE" iterative="true" group-dn-attribute="dn" group-name-attribute="uid">
              <group-to-principal base-dn="ou=groups,dc=group-to-principal,dc=example,dc=org" recursive="true" search-by="DISTINGUISHED_NAME">
                  <membership-filter principal-attribute="uniqueMember" />
              </group-to-principal>
          </group-search>
      </ldap>
  </authorization>

Un élément group-to-principal est ajouté ici. Cet élément est utilisé pour définir comment les recherches de groupes qui référencent l'entrée de l'utilisateur seront exécutées. Les attributs suivants sont définis :
  • base-dn: le nom unique du contexte à utiliser pour commencer la recherche.
  • recursive: indique si les sous-contextes peuvent également être recherchés. La valeur par défaut est false.
  • search-by: Le forme du nom de rôle utilisé dans les recherches. Valeurs valides SIMPLE et DISTINGUISHED_NAME. Valeur par défaut DISTINGUISHED_NAME.

Dans l'élément group-to-principal, il y a un élément membership-filter pour définir la correspondance.
  • principal-attribute : le nom de l'attribut d'entrée de groupe qui référence l'entrée utilisateur. La valeur par défaut est member.