1

Spring MVCアプリケーション(3.0.5バージョンを使用)があり、ユーザーの資格情報のみを認証するために、SpringLDAPを使用してActiveDirectoryにバインドする必要があります。アプリケーションはLinuxサーバーでホストされているため、クロスプラットフォームソリューションが必要です。また、アプリケーションはSpringSecurityを使用しません

この設定でユーザー認証を実装する効果的な方法は何ですか?Active DirectoryはFastBind制御(id = 1.2.840.113556.1.4.1781)をサポートしているので、それを活用したいと思います。必要なのは入力資格情報の検証だけであり、ADからのその他の情報は必要ないからです。

ありがとう!

更新(2012年7月16日):解決策の詳細で質問を更新し続けます。

@ ig0774からの回答に基づいて、次のconnection controlクラスを作成しました。

package com.company.authentication;

import javax.naming.ldap.Control;

public class FastBindConnectionControl implements Control {

    @Override
    public String getID() {
        return "1.2.840.113556.1.4.1781";
    }

    @Override
    public boolean isCritical() {
        return true;
    }

    @Override
    public byte[] getEncodedValue() {
        return null;
    }
}

次に、 connection-controlクラスAbstractContextSourceを使用して拡張しました。FastBind

package com.company.authentication;

import java.util.Hashtable;
import javax.naming.NamingException;
import javax.naming.directory.DirContext;
import javax.naming.ldap.Control;
import javax.naming.ldap.InitialLdapContext;
import org.springframework.ldap.core.support.AbstractContextSource;

public class FastBindActiveDirectoryContextSource extends AbstractContextSource {

    @Override
    protected DirContext getDirContextInstance(Hashtable env) throws NamingException {
        return new InitialLdapContext(env, new Control[] { new FastBindConnectionControl() });
    }
}

最後に、認証メカニズムをカプセル化するサービスクラス:

package com.company.authentication;

import javax.naming.AuthenticationException;
import javax.naming.directory.DirContext;
import org.springframework.ldap.core.ContextSource;
import org.springframework.ldap.support.LdapUtils;

public class ActiveDirectoryAuthService implements IAuthenticate {

    private ContextSource contextSource;
    public void setContextSource(ContextSource contextSource) {
        this.contextSource = contextSource;
    }

    @Override
    public boolean authenticate(final String login, String password) {
        try {
            DirContext ctx = contextSource.getContext(login, password);
            LdapUtils.closeContext(ctx);
            return true;
        }
        catch (Exception e) {
            return false;
        }
    }
}

Springアプリケーションのコンテキスト構成ファイルに、次のものを追加しました。

<bean id="ADContextSource" class="com.company.authentication.FastBindActiveDirectoryContextSource">
    <property name="url" value="ldaps://x.x.x.x:636" />
</bean>

<bean id="userAuthenticationService" class="com.company.authentication.ActiveDirectoryAuthService">
    <property name="contextSource" ref="ADContextSource" />
</bean>

最後に、userAuthenticationServiceBeanがクライアントクラス(ログインコントローラなど)に注入されます。

package com.company.web;

import com.company.authentication;

@Controller
public class LoginController {

    @Autowired
    private IAuthenticate userAuthenticationService;

    public String authenticateUser(String login, String password) {
      if (this.userAuthenticationService.authenticate(login, password)) {
          return "welcome";
      }
      else {
        return "login";
      }
    }
}
4

2 に答える 2

1

このOTNフォーラムの投稿でFastBind説明されているように、JNDIでのコントロールの実装は非常に簡単です。

基本的に、コントロールの新しいControlクラスを作成します。FastBind

class FastBindConnectionControl implements Control {
    public byte[] getEncodedValue() {
            return null;
    }
    public String getID() {
        return "1.2.840.113556.1.4.1781";
    }
    public boolean isCritical() {
        return true;
    }
}

次に、それを使用してLDAPコンテキストを作成します(エラー処理およびその他すべては無視されます)。

LdapContext ctx = new InitialLdapContext(env, new Control[] {new FastBindConnectionControl()});

理想的には、これはLDAP用のJNDIAPIのラッパーであるSpring-LDAPに簡単にプラグインできます。ただし、ビルトインのインターフェイスは接続制御を処理するためのパラメータを受け入れていないように見えるため、それを処理LdapContextSourceするための独自のサブクラスを作成する必要があるようです。AbstractContextSource十分に前進:

class FastBindLdapContextSource extends AbstractContextSource {
    protected DirContext getDirContextInstance(Hashtable env) {
        return new InitialLdapContext(env, new Control[] {new FastBindConnectionControl()});
    }
}

LdapContextSource次に、現在のインスタンスをのインスタンスに置き換える必要がありますFastBindLdapContextSource

ただし、このコンテキストソースはBIND操作にのみ使用できることに注意してください。Terry GardnerへのコメントでリンクしたMSDNドキュメントに記載されているように:

このモードの接続では、単純なバインドのみが受け入れられます。グループ評価が行われないため、接続は常に、他のすべてのLDAP操作の目的でバインドが発生していないかのように処理されます。

つまり、2種類のLDAPコンテキストを維持することを検討している可能性があります。1つはバインドを実行し、もう1つは実行する必要のあるルックアップを実際に実行します。


LdapTemplateのソースコードを見ると、このauthenticateメソッドは単なるバインド以上のものを実行しているように見えます。具体的には、ユーザーを検索してからバインドを試みます。なぜなら、有効になっているコンテキストを使用している場合FastBind、検索を実行できる可能性は低いからです(通常、ADは匿名接続での検索を許可しません)。基本的に、それはおそらく避ける必要があることを意味しますLdapTemplate

ただし、ADContextSource Beanへの参照を取得すると仮定すると、次のようなことを行うのに十分単純である必要があります。

boolean authenticate(String username, String password) {
    try {
        DirContext ctx = contextSource.getContext(username, password);
        LdapUtils.closeContext(ctx);
        return true;
    } catch (Exception e) {
        // note: this means an exception was thrown by #getContext() above
        return false;
    }
}

LdapTemplateこれはとにかく何をするかをかなり厳密に模倣します(欠落しているのはAuthenticatedLdapEntryContextCallback、このシナリオでは価値のない、と、AuthenticationErrorCallbackその動作が必要な場合に簡単に追加できる、だけです)。

于 2012-07-16T13:44:00.640 に答える
0

唯一の「ユーザーの資格情報をチェック」し、FastBindグループの決定を実行しないため、識別された名前と資格情報を使用してBIND要求をサーバーに送信するのが最善の場合があります。単純なBIND要求は、安全な接続を介して送信する必要があります。結果コードが0(ゼロ)の応答は、次のことを示します。

  1. サーバーはリッスンして応答しています
  2. 識別名が存在し、資格情報がサーバーデータベースに保存されている資格情報と一致している
  3. LDAPクライアントには、サーバー上のセッションを認証するための十分なアクセス許可があります

UnboundID LDAP SDKは、ディレクトリサーバーと対話するための最良のJava実装です。

于 2012-07-16T12:47:37.253 に答える