私はこの問題を解決するために何日もインターネットを検索してきました。
私は、ユーザーがASP.NETWebアプリケーションを使用してパスワードを変更できるようにする必要があるプロジェクトに取り組んでいます。
パスワード履歴を適用する必要があるため、「SetPassword」ではなく「ChangePassword」を使用する必要があります。また、LDS内のユーザーに必要以上の特権を許可しないようにする必要があります。私は開発環境でこのタスクを完了しようとしています。「Server1」(LDS、PingFederate、CA)と「Server2」(IIS)の2台のマシンがあります。2つのボックスの間にSSLが設定されていなかったため、問題が発生する可能性があると考えたため、昨日半日かけてCAを設定し、両方のマシンの証明書を作成しました。エラーログにエラーが表示されなくなったため、動作していると確信しています。SSLをオンにしたポート636を使用してLDPを使用してLDSにログインできます。また、これらのマシンはドメイン環境にありません。テストネットワーク上のすべてのマシンでhostsファイルを編集しました。
私はさまざまなバリエーションのコードを試しました:
public static bool ChangePassword(string email, string pwd, string newPwd)
{
DirectoryEntry user = GetCN(email);
string username = user.Properties["cn"][0].ToString();
DirectoryEntry de = new DirectoryEntry();
de.AuthenticationType = AuthenticationTypes.Secure | AuthenticationTypes.SecureSocketsLayer;
de.Path = user.Path;
de.Username = username;
de.Password = pwd;
try
{
Object obj = de.NativeObject;
de.Options.PasswordEncoding = PasswordEncodingMethod.PasswordEncodingSsl;
de.Options.PasswordPort = Convert.ToInt32(ConfigurationManager.AppSettings["LDAPPort_ExternalUsers"]);
de.Invoke("ChangePassword", new object[] { pwd, newPwd });
de.CommitChanges();
return true;
}
catch (Exception ex)
{
return false;
}
}
public static bool ChangePassword(string email, string pwd, string newPwd)
{
DirectoryEntry user = GetCN(email);
string username = user.Properties["cn"][0].ToString();
DirectoryEntry de = new DirectoryEntry(user.Path, username, pwd, AuthenticationTypes.Secure | AuthenticationTypes.SecureSocketsLayer);
try
{
de.Options.PasswordEncoding = PasswordEncodingMethod.PasswordEncodingSsl;
de.Options.PasswordPort = Convert.ToInt32(ConfigurationManager.AppSettings["LDAPPort_ExternalUsers"]);
de.Invoke("ChangePassword", new object[] { pwd, newPwd });
return true;
}
catch (Exception ex)
{
return false;
}
}
public static bool ChangePassword(string email, string pwd, string newPwd)
{
DirectoryEntry userInc = GetCN(email);
string username = userInc.Properties["cn"][0].ToString();
using (DirectoryEntry searchRoot = new DirectoryEntry(ConfigurationManager.AppSettings["LDAPConnectionString_ExternalUsers"], username, pwd, AuthenticationTypes.SecureSocketsLayer | AuthenticationTypes.Secure))
using (DirectorySearcher ds = new DirectorySearcher(searchRoot))
{
ds.Filter = "(|(objectCategory=user)(cn=" + username + "))";
SearchResult sr = ds.FindOne();
if (sr != null)
{
using (DirectoryEntry user = sr.GetDirectoryEntry())
{
user.Options.PasswordEncoding = PasswordEncodingMethod.PasswordEncodingClear;
user.Options.PasswordPort = Convert.ToInt32(ConfigurationManager.AppSettings["LDAPPort_ExternalUsers"]);
//user.Invoke("SetOption", new object[] { 6, Convert.ToInt32(ConfigurationManager.AppSettings["LDAPPort_ExternalUsers"]) });
//user.Invoke("SetOption", new object[] { 7, 1 });
user.Invoke("ChangePassword", new object[] { pwd, newPwd });
}
return true;
}
}
return false;
}
Object obj=de.NativeObject;の最初のバージョンで例外が発生します。これを使用してバインドが正しく行われているかどうかを判断し、これがポート389を介してユーザーを認証する方法であるため、デバッグ手順として挿入されました。例外は「ログオンの失敗:不明なユーザー名または不正なパスワード」です。
2番目のバージョンでde.Options.PasswordEncoding=PasswordEncodingMethod.PasswordEncodingSsl;で例外が発生します。例外は「ログオンの失敗:不明なユーザー名または不正なパスワード」です。
SearchResult sr = ds.FindOne();の3番目のバージョンで例外が発生します。例外は「ログオンの失敗:不明なユーザー名または不正なパスワード」です。
AuthenticatioTypes.Noneを使用してポート389でこのコードを実行しようとした場合| AuthenticationTypes.FastBind、de.Invoke( "ChangePassword"、new object [] {pwd、newPwd});で失敗します。「不明な名前」を除いて。これをSSLで実行するか、少なくともパスワードを平文で送信しないようにしたいと思います。HTTPS経由でサイトを実行しています。非SSL接続でパスワードを変更できるようにLDSのdsHeuristics値を変更しようとしましたが、それも機能しませんでした。
誰かが持っているかもしれないどんな提案でも大いに感謝されるでしょう。