web-dev-qa-db-ja.com

.NETでLDAPを認証する方法

任意のディレクトリサービスを使用して、Windowsオペレーティングシステムでアプリケーションのユーザー名とパスワードを認証したいと思います。たとえば、Microsoft Active Directory、Novell eDirecotry、SunOneなどです。このコードをMicrosoftActive Direcotryでc#を使用してネイティブに実行する方法はすでに知っています。 (私はADSIの使用と低レベルのcomコンポーネントの作成を完全に諦めました)

Novel eDirecotoryで認証しようとしている方法は、Monoプロジェクトをインストールしたことです。モノラルプロジェクト内では、Novell.Directory.ldap.dllが提供されます。コードはMicrosoft Active Directoryの場合と多少同じように見えます。( http://www.novell.com/coolsolutions/feature/11204.html

SunOneの場合、アクティブなディレクトリと同じコードを使用するように言われていますが、LDAP接続文字列は少し異なります。( http://forums.asp.net/t/354314.aspx ) ( http://technet.Microsoft.com/en-us/library/cc720649.aspx

私のプロジェクトを複雑にするために、ほとんどの顧客は「サービスアカウント」を使用します。これは、通常のユーザー名とパスワードを認証する前に、管理者のユーザー名とパスワードでバインドする必要があることを意味します。私の質問は2つの部分に分かれています。

1)上記で説明したことから、これは個々のディレクトリサービスに対して認証する必要がある正しい方向ですか?

2)このコードをまったく実行する必要がないと感じています。また、サービスアカウントの利用規定も重要ではないと感じています。私が気にしているのがWindowsマシンでのユーザー名とパスワードの認証だけである場合、なぜldapを使用する必要があるのですか?私はそれについて考えることを意味します。午前中にマシンにログインする場合、ログインするためだけにサービスアカウントを提供する必要はありません。 runas機能を使用すると、DOSプロンプトでユーザー名とパスワードを簡単に認証できます。拒否されるかどうかにかかわらず、テキストファイルを解析できます。私が使用しているWindowsオペレーティングシステムにユーザー名とパスワードを渡す方法は他にもあると思います。ユーザー名とパスワードが使用しているドメインで有効かどうかを教えてくれます。私は正しいですか?もしそうなら、あなたたちはどのような提案された方法を持っていますか?

Michael Evanchik www.MikeEvanchik.com

これはすべて、System.DirectoryServices.Protocolsを使用して実行できます。ディレクトリへのLdapConnectionを作成する場合は、サービスアカウントを使用してバインドし、その後のバインドを行って資格情報を認証できます。

サービスアカウントは通常、サーバーの認証メカニズムへのアクセスを制限するために使用されます。このようにして、通りにいるランダムな人がLDAPサーバーで認証を試みることはできません。

また、ログイン時に各ユーザーが識別名を提供することを期待していますか? Active Directoryでは、sAMAccountNameのみが必要ですが、eDirectoryやSunONEなどの他のプロバイダーは認証に識別名を必要とします。

このタイプの認証を実行するには、サーバーへの認証に提供されているサービスアカウントを使用し、指定されたユーザー名でユーザーを検索し、そのユーザーの識別名を取得する必要があります。次に、提供された識別名とパスワードを使用して認証できます。

これは、sAMAccountNameだけで満足できるActive Directoryを除いて、すべてのLDAPシステムで機能します。

3
Jared

質問を完全に理解できるかどうかはわかりませんが、状況によっては、アカウントを検索し、ユーザー名とパスワードとして資格情報を使用するだけで、ユーザーを認証するのが簡単であることがわかりました。

クエリが成功した場合は、提供されたすべてが正しいことを意味し、アカウントが見つからない場合は、何かが間違っていることを意味します。

//use the users credentials for the query
DirectoryEntry root = new DirectoryEntry(
    "LDAP://dc=domain,dc=com", 
    loginUser, 
    loginPassword
    );

//query for the username provided
DirectorySearcher searcher = new DirectorySearcher(
    root, 
    "(sAMAccountName=" + loginUser + ")"
    );    

//a success means the password was right
bool success = false; 
try {
    searcher.FindOne();
    success = true;
}
catch {
    success = false;
}

おそらく「ベストプラクティス」ではありませんが、発生している問題を回避できる可能性があります...

11
Hugoware

ドメイン資格情報に対してユーザー名とパスワードを認証する必要があり、LogonUserAPI関数を使用するWebサイトがありました。これをネットワークログオンに使用し(引数の1つはログオンタイプです)、資格情報を検証するだけで、runasのようにユーザープロファイルをロードするようなことはしません。唯一の注意点は、サービスアカウントがLogonUserを呼び出すために十分なアクセスを必要とすることです。 OSによって異なるため、MSDNのドキュメントでそのアクセスが何であるかを確認することをお勧めします。

0
pipTheGeek