2012-03-02 2 views
0

(私は経験豊かなプログラマーですが、LDAP、AD、Springを初めて使用しています)複雑なActive Directory/LDAPアカウントツリーを処理するためのSpring Security認証の設定方法を教えてください。

私たちはWindowsショップですので、すべての認証はActive Directoryで行われています。 Javaで書かれたサードパーティ製品を統合しようとしています。そのため、すべての認証はSpring Securityを使用して行います。これまでのところ、これまでに統合を行っていたので、オンラインになるとオンライン設定ができました。

問題がある、私たちのAD設定は少し複雑である:特に、私たちのユーザーアカウントがAD/LDAPツリー内のさまざまなノードに存在します。簡単な例を与えるために、LDAPツリーは次のようになります言う:

DC=my-domain,DC=com 
+ CN=Users 
++ CN=user1,CN=Users,DC=my-domain,DC=com 
+ CN=Staff 
++ CN=user2,CN=Staff,DC=my-domain,DC=com 

事は、私が見つけた例のすべては、私は USER1またはuser2が、どちらか一方だけを認証してみましょう、です。それは、次のXMLスニペットは、「グループ」の下で定義された役割に対して、USER1を認証するために動作しますされています

<security:ldap-server url="ldap://my-domain.com:389" manager-dn="CN=manager_svc,OU=System Users,DC=my-domain,DC=com" manager-password="MyPa55w0rd"/> 

<security:ldap-authentication-provider 
      user-dn-pattern="" 
      user-search-base="CN=Users,DC=my-domain,DC=com" 
      user-search-filter="(&amp;(sAMAccountName={0})(objectclass=user))" 
      group-search-base="OU=Groups,DC=mydomain,DC=com" 
      group-search-filter="member={0}" 
      /> 

が、彼は、ユーザーの検索ベースと一致していないので、それは、user2のを認証しません。逆に、私はユーザ検索ベースをCN=Staff,DC=my-domain,DC=comに変更することができます。これはuser2で動作しますが、user1では動作しません。

そこで問題は、私はAD/LDAPツリーに散らばっているユーザーアカウントに対してこの検索作業を作るのですか、ですか?私は2つの可能性を想像することができますが、私はどちらかまだ行う方法を考え出したていない:

  • 一方で、私は、ユーザーの検索ベースは複数値にすることができれば、それは簡単に私の問題を解決し、正しく:私は、ユーザーアカウントが見つかる可能性があるすべての場所に配置します。これまでのところ、これを行う私の試みはすべて、1つのエラーまたは他のもので満たされましたが、私はまだ実験中です。

  • OTOH、検索のサブツリースコープがあります。インタラクティブなLDAPツールでは、検索は単一レベルまたはサブツリーのいずれかであることがわかります。私が知る限りでは、ボックスの春はシングルレベルを行っています。私は、基本となるFilterBasedLdapUserSearchクラスは、私が欲しいもののように見えますが、私はXMLからtrueにそれを設定する方法を見つけることができませんsetSearchSubtree()メソッドを持っていることがわかります。 (ここでは、のは、基盤となるJavaプログラムを変更することは不可能であると仮定しましょう。)

それはおそらくはるかに効率的であるため、最初のオプションは、理想的であるが、それは可能ではない場合や第二に、私はそれを働かせることができると思う。

私は2番目のアプローチはイバラの豆牛車を使用して可能であるという疑いを持っていますが、私は次の豆について何を知っているので、私はむしろ、自分でそれらの茂みの中に歩いて渡るではないと思います。誰もが良いレシピを持っていますか?あなたが提供することができます任意の指導のために多くの

おかげで...

答えて

3

あなたはそれが可能である場合には、ADとの問題を引き起こすことができますが、ドメインのルートから検索を試みることができます。

また、明示的なbean configurationの使用は、おそらくあなたの最良の選択肢です。すべての必要な場所で検索するBindAuthenticator beanに、カスタムのLdapUserSearch実装を挿入できます。ドキュメントの例を見ると、FilterBasedLdapUserSearchの設定が表示されます。これらの2つを使用するか、最初からインターフェイスを実装することができます。ここでは例として、迅速なハックです:私はFilterBasedLdapUserSearchを使用して、スプリング・セキュリティの2.0.xと似たようなやった

<bean class="org.springframework.security.ldap.authentication.BindAuthenticator"> 
<constructor-arg ref="contextSource"/> 
<property name="userSearch" ref="customSearch"/> 
</bean> 

<bean id="customSearch" class="CustomLdapSearch"> 
<constructor-arg ref="contextSource"/> 
</bean> 
+0

この回答は役に立ちましたが、問題があります。たとえば、LdapUserSearchにする必要があるときは、LdapSearchとして "users"と "staff"を宣言しました。あなたはまた彼らを最終的に宣言しましたが、何にも設定しませんでした。 – fivedogit

+0

ありがとう、私はコードを更新しました。フィールドはコンストラクタで設定されます。 –

0

- ユーザーが広がった。

public class CustomLdapSearch implements LdapUserSearch { 
    public static final String SAM_FILTER="(&(sAMAccountName={0})(objectclass=user))" 

    final LdapUserSearch users; 
    final LdapUserSearch staff; 

    public CustomLdapSearch(BaseLdapPathContextSource contextSource) { 
     users = new FilterBasedLdapUserSearch("CN=Users,DC=my-domain,DC=com", SAM_FILTER, contextSource); 
     staff = new FilterBasedLdapUserSearch("CN=Staff,DC=my-domain,DC=com", SAM_FILTER, contextSource); 

    } 

    public DirContextOperations searchForUser(String username) { 
     try { 
      return users.searchForUser(username); 
     } catch(UsernameNotFoundException e) { 
      return staff.searchForUser(username); 
     } 
    } 
} 

は、その後にBindAuthenticator設定を変更します複数のノード間:

<bean id="ldapUserSearch" class="org.springframework.security.ldap.search.FilterBasedLdapUserSearch"> 
    <constructor-arg value=""/> <!-- optional sub-tree here --> 
    <constructor-arg value="(&amp;(sAMAccountName={0})(objectclass=user))"/> 
    <constructor-arg ref="contextSource"/> 
</bean> 


<bean id="ldapAuthProvider" 
     class="org.springframework.security.providers.ldap.LdapAuthenticationProvider"> 
    <constructor-arg> 
     <bean class="org.springframework.security.providers.ldap.authenticator.BindAuthenticator"> 
      <constructor-arg ref="contextSource"/> 
      <property name="userSearch" ref="ldapUserSearch"/> 
     </bean> 
    </constructor-arg> 
    <property name="userDetailsContextMapper" ref="userDetailsContextMapper"/> 
</bean> 


<bean id="contextSource" 
     class="org.springframework.security.ldap.DefaultSpringSecurityContextSource"> 
    <constructor-arg value="ldap://localhost:10389/CN=Users,DC=my-domain,DC=com"/> 
<!-- you may or may not need to connect with an account that can search --> 
    <!--<property name="userDn" value="uid=admin,ou=system"/>--> 
    <!--<property name="password" value="secret"/>--> 
</bean> 
2

私はちょうどprule年代のように、これは検索ベースとしてルートを使用しています(空の文字列値を検索ベースを使用してこれを解決答え)、しかし、私はまた、プロパティ "紹介"を "follow"に設定しなければならなかった、そうでなければ私はPartialResultExceptionを得ました!

DefaultSpringSecurityContextSource contextSource = new DefaultSpringSecurityContextSource(...); 
contextSource.setReferral("follow"); 
関連する問題