11.9.9.7. LDAP での承認とグループローディング

LDAP ディレクトリーには、属性によって相互参照されるユーザーアカウントとグループのエントリーが含まれます。LDAP サーバーの設定によっては、memberOf 属性を用いてユーザーエンティティーがユーザーが属するグループをマップしたり、 uniqueMember 属性を用いてグループエンティティーが属するユーザーをマップしたりすることがあります。また、両方のマッピングが LDAP サーバーによって維持されることもあります。
通常、ユーザーは簡単なユーザー名を使用してサーバーに対して認証を行います。グループメンバーシップ情報を検索する場合、使用中のディレクトリーサーバーに応じて、検索がこの単純名を使用して実行されたり、ディレクトリーのユーザーエントリーの識別名を使用して実行されたりします。
必ず最初に、サーバーへ接続するユーザーを認証する手順が実行されます。ユーザーの認証に成功した後、サーバーはサーバーグループをロードします。認証手順と承認手順はそれぞれ LDAP サーバーへの接続が必要になります。レルムはグループをロードする手順の認証接続を再使用して、このプロセスを最適化します。以下の設定手順のとおり、承認セクション内でルールを定義し、ユーザーの単純名を識別名に変換できます。認証中に行われる「ユーザー名から識別名へのマッピング」検索の結果はキャッシュされ、force が false に設定されている場合は承認クエリー中に再使用されます。force が true の場合は、承認中 (グループのロード中) に検索が再実行されます。通常、これは認証と承認が異なるサーバーによって実行される場合に行われます。
<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>

重要

これらの例では、実証目的で一部の属性をデフォルト値に指定します。デフォルト値を指定する属性は、サーバーによって永続化されると設定から削除されます。例外は force 属性で、デフォルト値の false に設定されていても必要となります。
username-to-dn
username-to-dn 要素は、ユーザー名をエントリーの識別名へマップする方法を指定します。この要素は、以下の両方の条件に見合う場合のみ必要となります。
  • 認証および承認手順は異なる LDAP サーバーに対するものである。
  • グループ検索が識別名を使用する。
1:1 username-to-dn

リモートユーザーによって入力されたユーザー名はユーザーの識別名であると指定します。
<username-to-dn force="false">
   <username-is-dn />
</username-to-dn>

これは 1:1 マッピングを定義し、追加の設定はありません。
username-filter

次のオプションは、前述の認証手順の簡単なオプションと似ています。指定のユーザー名に対して一致する指定の属性が検索されます。
<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>

設定可能な属性は次のとおりです。
  • base-dn: 検索を開始するコンテキストの識別名。
  • recursive: サブコンテキストが検索対象となるかどうか。デフォルトは false です。
  • attribute: 指定のユーザー名に対して一致されるユーザーエントリーの属性。デフォルトは uid です。
  • user-dn-attribute: ユーザーの識別名を取得するために読み取る属性。デフォルトは dn です。
advanced-filter

詳細フィルターを指定するオプションです。認証セクションでは、カスタムフィルターを使用してユーザーの識別名を見つけられます。
<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>

username-filter の例と同じ属性は、意味とデフォルト値も同じです。新たな属性は以下の 1 つのみです。
  • filter: ユーザー名が {0} プレースホルダーで置き換えられる、ユーザーのエントリーの検索に使用されるカスタムフィルター。

重要

フィルターの定義後も XML が有効である必要があるため、& などの特殊文字が使用される場合は、適切な形式が使用されるようにしてください。たとえば、& 文字には &amp; を使用します。
グループ検索

グループメンバーシップ情報の検索に 2 つのスタイルを使用できます。1 つ目のスタイルは、ユーザーがメンバーであるグループを参照する属性が含まれるユーザーのエントリーで、2 つ目のスタイルは、ユーザーエントリーを参照する属性が含まれるグループです。

使用するスタイルを選択できる場合、Red Hat はグループを参照するユーザーのエントリーに対する設定を使用することを推奨します。これは、検索を実行せずに既知の識別名の属性を読み取り、グループ情報をロードできるからです。別の方法は、ユーザーを参照するグループを特定するために大がかりな検索が必要となります。

設定を記述する前に、LDIF の例を見てみましょう。

例11.21 LDIF の例: プリンシパルからグループ

この例では、ユーザー TestUserOneGroupOne のメンバーで、 GroupOneGroupFive のメンバーです。グループメンバーシップは、memberOf 属性を使用して表されます。memberOf 属性は、ユーザー (またはグループ) がメンバーであるグループの識別名に設定されます。

ここには示されていませんが、複数の memberOf 属性を設定することも可能です (ユーザーが直接メンバーであるグループごとに 1 つ)。
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

例11.22 LDIF の例: グループからプリンシパル

この例でも、ユーザー TestUserOneGroupOne のメンバーで、 GroupOneGroupFive のメンバーですが、相互参照にはグループからユーザーへ属性 uniqueMember が使用されます。

グループメンバーシップの相互参照に使用される属性は繰り返しが可能で、GroupFive を確認すると、別のユーザー TestUserFive への参照があります (ここでは示されていません)。
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
一般的なグループ検索

前述の 2 つの方法の例を確認する前に、両方の方法に共通する属性を定義する必要があります。
<group-search group-name="..." iterative="..." group-dn-attribute="..." group-name-attribute="..." >
    ...
</group-search>
  • group-name: この属性は、ユーザーがメンバーであるグループのリストとして返されるグループ名に使用される形式を指定するために使用されます。これは、単純なグループ名またはグループの識別名になります。識別名が必要な場合は、この属性を DISTINGUISHED_NAME に設定できます。デフォルトは SIMPLE です。
  • iterative: ユーザーがメンバーであるグループを特定した後に、グループがメンバーであるグループを特定するため、グループを基に繰り返し検索するかどうかを指定するために使用される属性です。繰り返し検索が有効であると、他のグループのメンバーでないグループが見つかるか、サイクルが検出されるまで検索を続行します。デフォルトは false です。

巡回のグループメンバーシップは問題ではありません。検索済みグループの再検索を防ぐため、各検索の記録が保存されます。

重要

繰り返し検索が正しく実行されるようにするには、グループエントリーがユーザーエントリーと同じに見える必要があります。ユーザーがメンバーであるグループを特定するために使用された方法で、グループがメンバーであるグループを特定します。これは、グループ対グループのメンバーシップで相互参照に使用される属性の名前が変更されたり、参照の方向が変更されたりする場合は不可能です。
  • group-dn-attribute: 属性が識別名であるグループのエントリーです。デフォルトは dn です。
  • group-name-attribute: 属性が単純名であるグループのエントリーです。デフォルトは uid です。

例11.23 プリンシパルからグループへの設定例

前述の LDIF の例を基にした、ユーザーのグループを繰り返しロードする設定の例は次のとおりです。相互参照に使用される属性はユーザーの memberOf 属性です。
<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>

この設定で最も重要なことは、principal-to-group 要素が単一の属性で追加されていることです。
  • group-attribute: ユーザーがメンバーであるグループの識別名と一致する、ユーザーエントリー上の属性名。デフォルトは memberOf です。

例11.24 グループからプリンシパルへの設定例

この例は、前述のグループからプリンシパルへの LDIF の例に対する繰り返し検索を示しています。
<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>

ここでは、group-to-principal 要素が追加されています。この要素は、ユーザーエントリーを参照するグループの検索がどのように実行されるかを定義するために使用されます。以下の属性が設定されます。
  • base-dn: 検索を開始するために使用するコンテキストの識別名。
  • recursive: サブコンテキストも検索されるかどうか。デフォルトは false です。
  • search-by: 検索で使用されるロール名の形式です。有効な値は SIMPLE および DISTINGUISHED_NAME です。デフォルトは DISTINGUISHED_NAME です。

group-to-principal 要素内に、相互参照を定義する membership-filter 要素があります。
  • principal-attribute: ユーザーエントリーを参照する、グループエントリー上の属性名。デフォルトは member です。