2011-07-22 19 views
0

この問題を解決するためにインターネットを検索しています。AD LDS(ADAM)ChangePassword over SSL

私は、ユーザーがASP.NET Webアプリケーションを使用してパスワードを変更できるようにする必要があるプロジェクトに取り組んでいます。

私はパスワードの履歴を適用し、LDSのユーザーに必要以上の権限を与えないため、 "ChangePassword"ではなく "SetPassword"を使用する必要があります。私は開発環境でこの作業を完了しようとしています。私は2台のマシン "Server1"(LDS、PingFederate、CA)と "Server2"(IIS)を持っています。私は2つのボックスの間にSSLをセットアップしていなかったので問題が発生している可能性があると思っていたので、昨日半日CAをセットアップして両方のマシンの証明書を作成しました。私はエラーログに何もエラーがなくなってから動作していると確信しています。ポート636でSSLをチェックしてLDPを使用してLDSにログインできます。私はまた、これらのマシンがドメイン環境にないことに言及する必要があります。テストネットワーク上のすべてのマシンでhostsファイルを編集しました。

Iは、コードの異なるバリエーションを試みた:

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; 
} 

IがオブジェクトOBJ = de.NativeObjectにおける最初のバージョンに例外を取得;.私はバインドが正しく起こっているかどうかを判断するためにこれを使用していました。これはデバッグのステップとして挿入されました。これはポート389を介してユーザーを認証する方法です。例外は「ログオン失敗:不明なユーザー名またはパスワードが間違っています。

de.Options.PasswordEncoding = PasswordEncodingMethod.PasswordEncodingSslで2番目のバージョンの例外が発生しました。例外は「ログオン失敗:不明なユーザー名または不正なパスワード」です。

SearchResult sr = ds.FindOne()で3番目のバージョンの例外が発生しました。例外は「ログオン失敗:不明なユーザー名または不正なパスワード」です。

AuthenticatioTypes.Noneでポート389でこのコードを実行しようとすると、 AuthenticationTypes.FastBind、de.Invoke( "ChangePassword"、新しいオブジェクト[] {pwd、newPwd})で失敗します。 「Unknown Name」は例外です。私は本当にこれをSSLの下で実行するか、少なくともクリアなパスワードを送信しないようにしたいと思います。 HTTPS経由でサイトを実行しています。私はLDS上のdsHeuristicsの値を変更して、SSL以外の接続でパスワードを変更できるようにしようとしましたが、それもうまくいきませんでした。

誰かが持っている可能性のある提案は、非常に高く評価されるでしょう。

答えて

0

私は最終的にパスワードの変更作業を取得することができました。私はこれらの3つの機能を使用http://www.informit.com/articles/article.aspx?p=474649&seqNum=4

に提示された情報を使用:

NetworkCredential credential = new NetworkCredential("[user with access to the LDS", "pwd"); 
      DirectoryConnection connection; 
      try 
      { 
       //Setup our connection 
       connection = ADAuth.GetConnection(ConfigurationManager.AppSettings["LDAPServer_ExternalUsers"] + ":" + ConfigurationManager.AppSettings["LDAPPort_ExternalUsers"], credential, true); 

       //Attempt to change the password 
       ADAuth.ChangePassword(connection, ADAuth.GetDN(userID.Text).Properties["distinguishedName"].Value.ToString(), currPass.Text, newPass.Text); 

       //Send success message to user 
       ErrorLit.Text = "<p>Password change successful!</p>"; 
       //Dispose the connection 
       IDisposable disposable = connection as IDisposable; 
       if (disposable != null) 
        disposable.Dispose(); 
      } 
      catch (Exception ex) 
      { 
       //There was an error, tell the user 
       errors += "<li>Error changing password</li>"; 
       ErrorLit.Text = errors + "</ul>"; 
       return; 
      } 
:私はパスワードの変更を許可するページの背後にあるコードからそのような関数を呼び出し
private static DirectoryConnection GetConnection(string server, NetworkCredential credential, bool useSsl) 
{ 
LdapConnection connection = 
    new LdapConnection(server); 

    if (useSsl) 
    { 
      connection.SessionOptions.SecureSocketLayer = true; 
    } 
    else 
    { 
      connection.SessionOptions.Sealing = true; 
    } 

    connection.Bind(credential); 
    return connection; 
} 

private static void ChangePassword(DirectoryConnection connection, string userDN, string oldPassword, string newPassword) 
{ 
    DirectoryAttributeModification deleteMod = new DirectoryAttributeModification(); 
    deleteMod.Name = "unicodePwd"; 
    deleteMod.Add(GetPasswordData(oldPassword)); 
    deleteMod.Operation= DirectoryAttributeOperation.Delete; 

    DirectoryAttributeModification addMod = new DirectoryAttributeModification(); 
    addMod.Name = "unicodePwd"; 
    addMod.Add(GetPasswordData(newPassword)); 
    addMod.Operation = DirectoryAttributeOperation.Add; 

    ModifyRequest request = new ModifyRequest(userDN, deleteMod, addMod); 

    DirectoryResponse response = connection.SendRequest(request); 
} 

private static byte[] GetPasswordData(string password) 
{ 
    string formattedPassword; 
    formattedPassword = String.Format("\"{0}\"", password); 
    return (Encoding.Unicode.GetBytes(formattedPassword)); 
} 

関連する問題