2012-03-28 11 views
6

春3.1 のTomcat 6 *春3.1 LDAP認証プロセス:「クレデンシャルが不正」MSG資格情報が良好である

私はLDAPによる認証、春3.1 Webアプリケーションを作ることに取り組んでいます。

私が書いたJNDIスタイルのJavaプログラム(以下に引用)を使用してLDAP資格証明(ユーザー名、パスワード、LDAP URL、検索パターン)をテストしました。そのプログラムは、LDAPサーバー上で暗号化されているように見えるパスワードを含むユーザーの属性をすべてダンプしました。

Spring 3.1で同じ資格情報でログインしようとすると、「Bad Credentials」というエラーメッセージが表示されます。

私は、ログにこのメッセージを得た:私はパスワード比較とエンコーディングを実現するためにタグを使用してみましたが、それは助けにはならなかった私の*の-security.xmlで

DEBUG [org.springframework.security.authentication.ProviderManager:authenticate] (ProviderManager.java:152) - Authentication attempt using org.springframework.security.ldap.authentication.LdapAuthenticationProvider 
DEBUG [org.springframework.security.ldap.authentication.AbstractLdapAuthenticationProvider:authenticate] (AbstractLdapAuthenticationProvider.java:51) - Processing authentication request for user: John.A.Smith 
DEBUG [org.springframework.security.ldap.authentication.BindAuthenticator:bindWithDn] (BindAuthenticator.java:108) - Attempting to bind as uid=John.A.Smith,ou=People,o=acme.com,o=acme.com 
DEBUG [org.springframework.security.ldap.DefaultSpringSecurityContextSource$1:setupEnvironment] (DefaultSpringSecurityContextSource.java:76) - Removing pooling flag for user uid=John.A.Smith,ou=People,o=acme.com,o=acme.com 
DEBUG [org.springframework.security.ldap.authentication.BindAuthenticator:handleBindException] (BindAuthenticator.java:152) - Failed to bind as uid=John.A.Smith,ou=People,o=acme.gov: org.springframework.ldap.AuthenticationException: [LDAP: error code 32 - No Such Object]; nested exception is javax.naming.AuthenticationException: [LDAP: error code 32 - No Such Object] 
DEBUG [org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter:unsuccessfulAuthentication] (AbstractAuthenticationProcessingFilter.java:340) - Authentication request failed: org.springframework.security.authentication.BadCredentialsException: Bad credentials 

を。私はmd4、md5、plaintext、sha、sha-256、{ssha}、{sha}を無駄に使ってみました。

<s:authentication-manager> 
     <s:ldap-authentication-provider user-dn-pattern="uid={0},ou=People,o=noaa.gov" > 
      <s:password-compare hash="md5"> 
      <s:password-encoder hash="md5"/> 
      </s:password-compare> 
     </s:ldap-authentication-provider> 
     </s:authentication-manager> 

私のネットワーキンググループは、大きく、遅く、官僚的な組織です。彼らが使用しているエンコーディングを、もしあれば、彼らに連絡せずに伝える方法はありますか?

私がチェックアウトできるものはありますか?

これが私の最後の試みと私は

おかげで接続することができましたJavaのLDAPのデモのように私*の-security.xmlです。

マイ* -security.xmlファイル:

import javax.naming.*; 
import javax.naming.directory.*; 
import java.util.*; 
import java.sql.*; 

public class LDAPDEMO { 

    public static void main(String args[]) { 

     String lcf    = "com.sun.jndi.ldap.LdapCtxFactory"; 
     String ldapurl   = "ldap://ldap-itc.sam.acme.com:636/o=acme.com"; 
     String loginid   = "John.A.Smith"; 
     String password   = "passowordforjohn"; 
     DirContext ctx   = null; 
     Hashtable env    = new Hashtable(); 
     Attributes attr   = null; 
     Attributes resultsAttrs = null; 
     SearchResult result  = null; 
     NamingEnumeration results = null; 
     int iResults    = 0; 


     env.put(Context.INITIAL_CONTEXT_FACTORY, lcf); 
     env.put(Context.PROVIDER_URL, ldapurl); 
     env.put(Context.SECURITY_PROTOCOL, "ssl"); 
     env.put(Context.SECURITY_AUTHENTICATION, "simple"); 
     env.put(Context.SECURITY_PRINCIPAL, "uid=" + loginid + ",ou=People,o=acme.com"); 
     env.put(Context.SECURITY_CREDENTIALS, password); 
     try { 

      ctx  = new InitialDirContext(env); 
      attr = new BasicAttributes(true); 
      attr.put(new BasicAttribute("uid",loginid)); 
      results = ctx.search("ou=People",attr); 

      while (results.hasMore()) { 
       result  = (SearchResult)results.next(); 
       resultsAttrs = result.getAttributes(); 

       for (NamingEnumeration enumAttributes = resultsAttrs.getAll(); enumAttributes.hasMore();) { 
        Attribute a = (Attribute)enumAttributes.next(); 
        System.out.println("attribute: " + a.getID() + " : " + a.get().toString()); 


       }// end for loop 

       iResults++; 
      }// end while loop 

      System.out.println("iResults == " + iResults); 

     }// end try 
     catch (Exception e) { 
      e.printStackTrace(); 
     } 



    }// end function main() 
}// end class LDAPDEMO 

ソリューション:

ここ
<beans xmlns="http://www.springframework.org/schema/beans" 
    xmlns:s="http://www.springframework.org/schema/security" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xsi:schemaLocation="http://www.springframework.org/schema/beans 
    http://www.springframework.org/schema/beans/spring-beans-3.0.xsd 
    http://www.springframework.org/schema/security 
    http://www.springframework.org/schema/security/spring-security-3.1.xsd"> 



    <s:http auto-config="true" use-expressions="true"> 
    **<s:intercept-url pattern="/welcome*" access="isAuthenticated()" />** 
    <s:form-login login-page="/login" default-target-url="/welcome" 
     authentication-failure-url="/loginfailed" /> 
    <s:logout logout-success-url="/logout" /> 
    </s:http> 



    <s:ldap-server url = "ldap://ldap-itc.sam.acme.com:636/o=acme.com"/> 

    <s:authentication-manager> 
    <s:ldap-authentication-provider user-dn-pattern="uid={0},ou=People,o=noaa.gov" /> 
    </s:authentication-manager> 

</beans> 

は、同じ資格情報を使用してワークスJNDIスタイルLDAP Javaプログラムです


ルーク・テイラーからのこのコメントは、私は私の設定作業を取得助け:

あなたの設定は、あなたがLDAP サーバーのURLに「O = acme.com」を持っているし、また、「使用しているという点で間違っていますユーザーDNパターンで「o = acme.com」と入力します。

私は "o = acme.com"をDNパターンから取り出し、LDAPが機能しました。私は当初、LDAP URLとDNパターンの両方に "o = acme.com"を入れました。なぜなら私はSpring 3.1とLDAPには新しく、これはJava JNDIバージョンのLDAPデモ私は置き換えているレガシーコードに基づいて書きました。

ここにmy * -securityの最終版があります。XML

<beans xmlns="http://www.springframework.org/schema/beans" 
    xmlns:s="http://www.springframework.org/schema/security" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xsi:schemaLocation="http://www.springframework.org/schema/beans 
    http://www.springframework.org/schema/beans/spring-beans-3.0.xsd 
    http://www.springframework.org/schema/security 
    http://www.springframework.org/schema/security/spring-security-3.1.xsd"> 



    <s:http auto-config="true" use-expressions="true"> 
    **<s:intercept-url pattern="/welcome*" access="isAuthenticated()" />** 
    <s:form-login login-page="/login" default-target-url="/welcome" 
     authentication-failure-url="/loginfailed" /> 
    <s:logout logout-success-url="/logout" /> 
    </s:http> 



    <s:ldap-server url = "ldap://ldap-itc.sam.acme.com:636/o=acme.com"/> 

    <s:authentication-manager> 
    <s:ldap-authentication-provider user-dn-pattern="uid={0},ou=People" /> 
    </s:authentication-manager> 

</beans> 

は、私は彼の他のコメントを探検し、私は戻って私がする必要がある、あるいは場合は、パスワードのエンコードを置くことができるかどうかを確認するつもりです。

+0

別のメモ。サーバがどのアルゴリズムを使用しているかわからないので、実際には複数のサーバを使用している可能性があるので、パスワードエンコーディングを元に戻すことはできません。パスワードをハッシュすることは、パスワードデータベースを読みにくくすることによってパスワードデータベースを保護することです。クライアント認証をより安全にすることではありません(これについては多くの議論があります)。あなたのアプリからLDAPサーバーへのネットワークの盗聴を防止したい場合は、おそらくSSL接続を使用するのが最も簡単な方法です。 –

答えて

3

あなたのJavaの例は、標準的なバインド認証を使用しているが、あなたは、ユーザーのパスワードにLDAP compare operationを行うには春のセキュリティ設定を設定している:あなたが役割をしたくない場合は、このような何かを試してみてください。これは、LDAPサーバーがSpring SecurityのMD5エンコーダーと同じパスワードエンコード形式を使用していないために失敗します。比較操作を成功させるには、格納されている値がディレクトリに送信された文字列と一致する必要があります。ほとんどの場合、標準のLDAP(バインド)認証を使用します。おそらく、認証プロバイダのためにBean設定を使用する必要があります。試してみてください:

<s:ldap-server id="contextSource" url="ldap://ldap-itc.sam.acme.com:636/o=acme.com"/> 

<bean id="ldapAuthProvider" class="org.springframework.security.ldap.authentication.LdapAuthenticationProvider"> 
<constructor-arg> 
    <bean class="org.springframework.security.ldap.authentication.BindAuthenticator"> 
    <constructor-arg ref="contextSource"/> 
    <property name="userDnPatterns"> 
     <list><value>uid={0},ou=People</value></list> 
    </property> 
    </bean> 
</constructor-arg> 
<constructor-arg> 
    <bean class="org.springframework.security.ldap.authentication.NullLdapAuthoritiesPopulator"/> 
</constructor-arg> 
    <property name="authoritiesMapper"> 
    <bean class="class="org.springframework.security.core.authority.mapping"> 
     <property name="defaultAuthority" value="ROLE_USER" /> 
    </bean> 
    </property> 
</bean> 

<s:authentication-manager> 
    <s:authentication-manager ref="ldapAuthProvider" /> 
</s:authentication-manager> 

the LDAP chapter of the reference manualもお読みください。

また、認証に失敗した理由を知りたい場合は、LDAPサーバー自体のログを確認するのが最適です。完全なアクセス権がない場合は、どのように設定されているかを調べて、フルコントロールのあるローカルサーバ(OpenLDAPなど)を使用してください。

+0

こんにちはルーク。私は、Spring 3.1のLDAPの章を何度か読んだ。簡単ですが、私は春だけでなくLDAPも新しくなっています。私はあなたのコメントを理解していることを確認したい。 タグを削除した場合は、引用符で囲まれたJavaプログラムが標準バインディングを使用するように変更されます。パスワード比較は一切行っていませんか? Springはデフォルトでパスワードの比較を行いますか?私はそれをしないために何かを設定する必要がありますか? – Steve

+0

パスワードが一致していないと、パスワードを入力することはできません(パスワードの大文字と小文字は異なる場合があります)。すでに動作していることを実証し、パスワード比較を忘れているので、バインド認証を使用するべきです。これは通常、バインドが無効の場合にのみ使用されます。私が提供した設定を試しましたか?もしそうなら、何が起こったのですか? –

+0

Luke、あなたのコメントに照らして、私は* server.xmlと元の投稿全体を変更しました。私は少しあなたの設定を勉強する必要があります。可能であれば、私はSpring 3.1スタイルを書く方法を見つけたいと思います。私はそれに打撃を与え、それがどのように機能するかを伝えます。ありがとう、トン。 – Steve

0

私は運を試してみます。数週間前、私は同様の問題を抱えていました。エラーなし、正しいユーザー/パス、Bad Credentialsエラー。

まず、スプリングセキュリティのデバッグレベルを有効にすることをお勧めします。あなたはより多くの情報を得るでしょう。私の場合、これは私のユーザが関連する役割を持たず、Springがそれを「悪い認証情報」のエラーとして扱っていたことが問題であることを確認するのに役立ちました。あなたのケースかもしれません。それを確認してください。

とにかく、悪い資格情報は、常にユーザー/パスが間違っていることを意味しません。

EDIT:log4jのを使用してデバッグレベルを活性化するために:ROLE_ADMINを:あなた構成で

<logger name="org.springframework.security"> 
    <level value="DEBUG" /> 
</logger> 

、ウェルカムページへのアクセスは、adminロールが必要であることを読み取ることができます。

<s:intercept-url pattern="/welcome*" access="isAuthenticated()" /> 
+0

私はSpringとLDAPの新機能です。 Spring Securityでデバッグレベルをアクティブにするにはどうしたらいいですか? 役割をユーザーに関連付けることはできませんか? 中立的な役割をユーザーに関連付けることはできますか?私たちは本当にユーザーのための役割を持っていません。 – Steve

+0

私は答えを編集しました。ロールを必要としない場合は、ロールをアクセスに関連付けないでください。 – jddsantaella

+0

あなたが提案した新しいアクセス値を試しました。変化なし。あなたが上に引用したロガーxmlをどこに置くのですか? – Steve

関連する問題