私が働いている場所では、2 つの認証モードがあります。
- CAS ( http://www.jasig.org/cas )
- LDAP
CAS が主要な方法ですが、トラフィックのピーク時には信頼性が低いことが多いため、CAS がダウンしていることに気付いた場合のフォールバック モードとして LDAP を使用しています。以前は、LDAP フォールバックを行うために PHP を使用していましたが、適切なパフォーマンスが得られました。予想されるネットワーク ラグ タイム以外に、ログイン中に目立った遅延はありませんでした。LDAP を使用してログインを完了するには、おそらく 250 ~ 500 ミリ秒かかりました。
現在、私たちは新しいシステムを作成しており、PHP ではなく ASP.NET MVC4 をプラットフォームとして選択しました。私は、このフォールバックを再び機能させることを任されています。私は約6時間髪を引き抜いてきましたが、さまざまなことを何度も試してみましたが、同じ結果が得られました(おそらく私は正気ではありません). ようやく LDAP に接続し、ユーザーを認証し、LDAP から属性を取得することができました。ただし、どの方法を試しても、クエリの完了には一貫して 4.5 秒かかります。
PHP バージョンが 1/8 の時間でほぼ同じことを行うことができ、.NET フレームワークが LDAP/ActiveDirectory に対して優れたサポートを提供しているように見えるので、これは私にとって非常に驚くべきことです。私は信じられないほどひどく間違ったことをしていますか?
現在の私の関数の中身は次のとおりです (これは、1 回の 4.5 秒のクエリですべてを実行する最新の反復です)。
public Models.CASAttributes Authenticate(string username, string pwd)
{
string uid = string.Format("uid={0},ou=People,o=byu.edu", username);
LdapDirectoryIdentifier identifier = new LdapDirectoryIdentifier("ldap.byu.edu", 636, false, false);
try
{
using (LdapConnection connection = new LdapConnection(identifier))
{
connection.Credential = new NetworkCredential(uid, pwd);
connection.AuthType = AuthType.Basic;
connection.SessionOptions.SecureSocketLayer = true;
connection.SessionOptions.ProtocolVersion = 3;
string filter = "(uid=" + username + ")";
SearchRequest request = new SearchRequest("ou=People,o=byu.edu", filter, SearchScope.Subtree);
Stopwatch sw = Stopwatch.StartNew();
SearchResponse response = connection.SendRequest(request) as SearchResponse;
sw.Stop();
Debug.WriteLine(sw.ElapsedMilliseconds);
foreach (SearchResultEntry entry in response.Entries)
{
Debug.WriteLine(entry.DistinguishedName);
foreach (System.Collections.DictionaryEntry attribute in entry.Attributes)
{
Debug.WriteLine(attribute.Key + " " + attribute.Value.GetType().ToString());
}
Debug.WriteLine("");
}
}
}
catch
{
Debugger.Break();
}
Debugger.Break();
return null; //debug
}
これの PHP バージョンは、次のシーケンスに従います。
- 匿名でバインドし、basedn と cn を使用してユーザー情報を検索します
- ユーザーのユーザー名とパスワードを使用して再度バインドし、認証されているかどうかを確認します
2 つのバインド (接続?) を、.NET バージョンが 1 つ実行するのにかかる時間の 1/8 で実行します! この種のことで、私は何かが欠けていると思います。
以下のサイトを参考に方法を試してみました。
- http://roadha.us/2013/04/ldap-authentication-with-c-sharp/ - やりたいことを実行するには 2 つのクエリが必要で、遅すぎました。私はおそらく6回の異なる試みを行いました(認証と接続設定の変更など)。
- http://web.byu.edu/docs/ldap-authentication-0 - 1 つの PHP バージョンですが、下部に .NET に関する小さなスニペットがあります。プロファイルも取得する必要がありましたが、それらは正確に説明するものではありませんでした。
- System.DirectoryServices は遅いですか? - 現行版
編集:
Wireshark を使用して、次の要求が行われていることを確認しました。
- bindRequest が uid を渡す (デルタ 0.7ms)
- bindResponse の成功 (差分 2 ミリ秒)
- searchRequest "ou=People,o=byu.edu" wholdSubtree (デルタ 0.2ms)
- searchResEntry "uid=私の uid ,ou=人,o=byu.edu" | searchResDone 成功 1 件の結果 (デルタ 10.8ms)
- unbindRequest (デルタ 55.7ms)
明らかに、オーバーヘッドは要求ではなく .NET から発生しています。これらは、どのような方法、形、または形であっても、合計して 4.5 秒にはなりません。