18

ログインして Active Directory に対してユーザーを確認する必要がある MVC アプリケーションがあります。メソッドを使用してPrincipalContext.ValidateCredentialsいますが、常に の認証を取得しfalseます。

サーバーへの接続は問題ありません。で問題が発生しているようValidateCredentialsです。

これが私のコードです:

public static bool IsAuthenticated(string domain, string username, string pwd) {
    bool IsAuthenticated = false;

    try {
        PrincipalContext insPrincipalContext = 
            new PrincipalContext(ContextType.Domain, domain, "DC=c1w,DC=com");

        username = "c1w\\" + username;

        IsAuthenticated = insPrincipalContext.ValidateCredentials(username, pwd);
    }
    catch (Exception ex)
    {
        // Rethrow this exception
        ExceptionPolicy.HandleException(ex, "Exception Policy");
    }

    return IsAuthenticated;
}

なぜこれが起こるのか知っている人はいますか?

4

3 に答える 3

19

仕組みは次のとおりです。まず、、、およびコンテキスト オプションを使用ValidateCredentials(string, string)して認証を試みます。これが失敗した場合、 と で再試行します。NegotiateSigningSealingSimpleBindSecureSocketLayer

問題は、NT4 (別名「レガシー」、別名「ダウンレベル名」) 形式 ( DOMAIN\UserName、より正確にはNetBiosName\SamAccountName) が Negotiate で機能しないことです。ただし、SimpleBind では機能します。

したがって、2 パラメーター メソッドを呼び出すときにおそらく発生するのValidateCredentials()は、NT4 形式が気に入らないために最初に Negotiate を使用して失敗し、次にシンプル バインドを使用すると再び失敗することです。

私自身のテスト中に、シンプル バインドを使用するようにフォールバックしても失敗する理由は、SimpleBind を使用しているだけではないことがわかりました。SimpleBindプラスを使用していSecureSocketLayerます。これは、Active Directory サーバーが SSL を使用するように正しく設定されていない場合でも失敗することを意味します (テスト環境の一般的なシナリオ)。

コメントの 1 つで述べたように、絶対にSimpleBind(なしで) 単独で使用したくありませんSecureSocketLayer。そうしないと、パスワードがネットワーク経由でプレーン テキストで送信されます。

実際のところ、一部の Active Directory システムでは単純なバインドの使用がまったく許可されていないことがわかりました。そのため、Negotiate で機能させる必要があります。

この問題に対処する 2 つの方法を見つけました。

1) すべてが同じドメインで発生している場合はValidateCredentials、ユーザー名 (SAM アカウント名) のみを使用して呼び出すことができ、「DOMAIN\」の部分は省略できます。すると、Negotiateで1回目はちゃんと動くようになります。

2) 複数のドメインが関係している可能性があるため (つまりDomain1\UserADomain2\UserA異なる人物である)、ドメインの部分が重要な場合は、もう少し複雑になります。この場合、私が最終的に行ったことは、NT4 名 (DOMAIN\User) を「ユーザー プリンシパル名」形式 (例: LogonName@domain.com) に変換することでした。これを行うには、いくつかの方法があります。最も簡単な方法は、おそらく の 3 パラメーター オーバーロードを使用して、結果のプロパティUserPrincipal.FindByIdentity()の値を取得することです。UserPrincipalNameもう 1 つの方法は、一致する値を持つユーザーのプロパティに対してDirectorySearcherand クエリを使用することです。注: このソリューションは、関係するすべてのドメインが同じフォレストにある場合にのみ機能します。LDAP://domainuserPrincipalNamesAMAccountName

于 2015-07-17T14:18:22.117 に答える
9

「pwd」変数を初期化する場所がわかりません。このメソッドでContextOptionを使用して、必要な動作を正確に指定する必要があります。回答が広すぎて申し訳ありませんが、質問の詳細はあまりありません

于 2010-03-02T14:16:15.857 に答える