2012-02-20 6 views
2

DirectoryServicesを使用してユーザーを認証するイントラネットWebアプリケーション用のメソッドを作成する必要があります。これは、既定のドメインまたはユーザーが指定したドメインに対して行われます。ユーザがウェブサーバと同じドメイン内にあり、あるとき、最初のケースを使用することができますが"username""passwordの形で資格情報」または"domain\username""password" を与えるいずれかのことができるようになります私のログインでDirectoryServicesを使用したドメイン間認証

を形成。かなりstraightfoward私が使用するコードは次のとおりです。

string domain = ""; 
// Code to check if the username is in form of "domain\user" or "user" 
string username = ParseUsername(username, out domain); 
if(domain == "") 
    domain = defaultDomain; 

PrincipalContext context = new PrincipalContext(ContextType.Domain, domain, username, password); 
bool IsAuthenticated = context.ValidateCredentials(username, password) 

私は別のドメインにアクセスしようとする場合に、コールをバインドするためにPrincipalContextコンストラクタにユーザー名とパスワードを渡すローカルドメインの場合

。そのコードは正常に動作します。しかし、ユーザー名で指定されている別のドメインと照合しようとすると、「サーバーに接続できませんでした」というエラーが表示されます。

ContextOptions.SimpleBindContextOptions.Negotiateなど別のContextOptionsを使ってみましたが、いつも同じ結果が出ているようです。

アプリケーションは、単一ドメインまたは複数ドメイン環境のいろいろな顧客に出荷されているので、これを実装する必要があります。 "リモート"ドメインの場合に指定する必要があるものはありますか?これはさまざまな環境で展開されるため、コードは柔軟にする必要があります。

おかげで

EDIT:私は、私はそれが同様に提供し、他の機能を利用するためにDirectoryServices.AccountManagementPrincipalContextを使用してそれを行うことを好むことを、指摘しなければなりません。

私のテストでは、私のDevマシンは10.0.0。*のネットワーク上にあり、私がテストしている2番目のドメインは10.0.1。*です。私はルートとすべてを持っている、と私はsuccesfuly LDAPクライアントを使用して接続することができますので、私のasp.netアプリケーションを介してドメインに接続することはできません質問です。

答えて

3

私はこの問題に対するこの解決策を考え出しました。

信頼関係または隔離されたネットワークでも複数のドメインをサポートするには、最初にweb.configにNameValueCollectionを追加して、ドメインとそのドメインコントローラをリストします。

<domains> 
    <add key="domain1" value="10.0.0.1"/> 
    <add key="domain2" value="10.0.1.11"/> 
    </domains> 

this so questionで設定追加の詳細)

次のステップは、私が質問に言及するようにして、ユーザの資格情報からドメインを読み取ることでした。ドメインを取得したら、適切なLDAP接続文字列を取得するために、設定値からドメインコントローラを検索しようとします。だから私の方法はこれです:

private string GetLDAPConnection(string a_Domain, string a_Username, string a_Password) 
{ 
    // Get the domain controller server for the specified domain 
    NameValueCollection domains = (NameValueCollection)ConfigurationManager.GetSection("domains"); 
    string domainController = domains[a_Domain.ToLower()]; 

    string ldapConn = string.Format("LDAP://{0}/rootDSE", domainController); 

    DirectoryEntry root = new DirectoryEntry(ldapConn, a_Username, a_Password); 
    string serverName = root.Properties["defaultNamingContext"].Value.ToString(); 
    return string.Format("LDAP://{0}/{1}", domainController, serverName); 
} 

私は戻って、適切な接続文字列を取得したら、私は私にこの点から適切なLDAPに

... 
    string ldapConn = GetLDAPConnection(domain, username, a_Password);        
    DirectoryEntry entry = new DirectoryEntry(ldapConn, username, a_Password);   

    try 
    { 
     try 
     { 
      object obj = entry.NativeObject; 
     } 
     catch(DirectoryServicesCOMException comExc) 
     { 
      LogException(comExc); 
      return false; 
     } 

     DirectorySearcher search = new DirectorySearcher(entry); 
     search.Filter = string.Format("(SAMAccountName={0})", username); 
     search.PropertiesToLoad.Add("cn"); 
     SearchResult result = search.FindOne(); 

に取り組むことで、ユーザを認証するために、新たに電話をかけますユーザーのグループメンバーシップなど、他のすべてのクエリを実行することもできます。

リモートドメインへの呼び出しをユーザーにバインドする必要があるため、「呼び出し」ユーザーの資格情報を使用します。このようにして、ユーザgetは認証され、コールは特定のユーザにバインドされます。さらに、ユーザーがドメインを指定せずに資格情報を提供する場合は、「デフォルト」ドメインを指定します。

しかし私はこれを、私が望むようにPrincipalContextを使用して管理しませんでしたが、明るい面では、このソリューションは古い.NET 2.0アプリケーションにも適用されます。

これが問題の最良の解決策であるかどうかはわかりませんが、これまで行ってきたテストではうまくいくようです。

1

downvotedが得られた理由はわかりませんが、ここでは間違っていると思われます。コードがホストされているサーバー/ドメインと、接続しようとしているドメイン間の信頼レベルが確立されていない可能性があります。私はなぜそれが起こっているかもしれない理由をあなたに提供することはできません。

[EnvironmentPermissionAttribute(SecurityAction.LinkDemand, Unrestricted = true)] 

あなたの機能の上にこれを追加してみてください、それはあなたが通過するのに役立ちますが、別に私は可能なすべてのユーザーに対してWinNTのドメインでの検索に間違っているだろう、なぜ表示されないことからかどうかを確認することができます。これが役に立ったらいいですか

+0

セキュリティの制限は私の最初の推測です。しかし、このメソッドの古い実装では、古い.NET 2.0ライブラリのDirectoryEntryとDirectorySearcherを使用していました。その場合、コールをバインドするためにユーザー名とパスワードを渡す必要があり、これがダブルホップの問題を解決します。さて、私はまったく接続していないようです。 主な相違点は、より多用途になるように、ユーザーが所属するドメインを指定できるようにする必要があることです。 –

+0

私が働いていた場所が新しいドメインに移行することに決めたとき、私は同様の問題を抱えていました。移行プロセスでは、両方のドメインをアクティブに保つ必要がありました。そこには信頼の問題があることがわかりましたが、解決策を決して決めることはできませんでした。代わりに、WinNTのアプローチで、ネットワーク全体でuserIDを検索し、そのオブジェクトを取得してから、必要に応じて操作を行いました。 WinNTが実行可能かどうかを確認するために、両方の方法のレイテンシチェックも行いましたが、それは適切な選択であることが判明しました。 – gizgok

+0

@NikosSteiakakis解決策を見つけ出すには、ここに書いてください。 – gizgok

関連する問題