2014-11-14 118 views
0

我想使用.NET 3.5中引入的AccountManagement命名空間來查找用戶並設置其密碼。但是,ADLDS服務器不屬於我們公司的域名,所以我使用ContextType.Machine。當我搜索用戶時,它從來沒有找到(我懷疑它是在錯誤的容器中搜索,但根據使用ContextType.Machine時的文檔,您無法指定容器)。如何在遠程LDAP服務器上的特定OU中搜索用戶?

using (var context = new PrincipalContext(ContextType.Machine, "test-server", null, "username", "password")) { 
    using (var u = UserPrincipal.FindByIdentity(context, "SuperAdmin")) { 
     //u is always null. :(
    } 
} 

但是,我知道我可以使用純醇」 DirectoryEntry找到用戶:

using (var de = new DirectoryEntry("LDAP://test-server:389/CN=SuperAdmin,CN=SuperUsers,OU=test-server,DC=foo,DC=bar,DC=com", "username", "password", AuthenticationTypes.Secure)) { 
    //The user is found, but SetPassword fails with "The directory property cannot be found in the cache" 
    de.Invoke("SetPassword", new object[] { "foobar" }); 
} 

最後一件事要指出的是,我可以使用ADSI編輯更改與這些相同的憑據密碼。是否可以使用較新的目錄對象執行此搜索?

回答

0

這真是一個老問題,但就在最近,我不得不對類似的項目工作...如果有人跑進了同樣的問題,我會發布了答案。

使用UserPrincipal類找不到user的原因是,正如您所提到的,您正在使用ContextType.Machine進行搜索。但在DirectEntry類中,您只是在執行簡單的LDAP://查詢。

這是我的解決方案。

我將我的服務器信息存儲在.config文件中。

... 
//Server name and port 
<add key ="ADLDS_Server" value="Servername:port"/> 
//Note* depending on structure container will be different for everybody 
<add key ="ADLDS_Container" value="CN=Some Value, DC=some value,DC=value"/> 
... 

我然後創建ADLDSUtility類返回PrincipalContext對象。

... 
using System.DirectoryServices.AccountManagement 
... 
public class ADLDSUtility 
{ 
    public static ContextOptions ContextOptions = ContextOptions.SecureSocketLayer | ContextOptions.Negotiate; 

    public static PrincipalContext Principal 
    { 
     get 
     { 
      return new PrincipalContext(
       ContextType.ApplicationDirectory, 
       ConfigurationManager.AppSettings["ADLDS_Server"], 
       ConfigurationManager.AppSettings["ADLDS_Container"], 
       //you can specify username and password if need to 
       ContextOptions); 
     } 
    } 

從那裏,我寫了一個method接受(用戶名,currentPassword和NEWPASSWORD)爲PARAMATERS。

public void ChangePassword(string userName, string currentPassword, string newPassword) 
    { 
     using (PrincipalContext ctx = ADLDSUtility.Principal) 
     { 
      using (UserPrincipal principal = new UserPrincipal(ctx)) 
      { 
       using (var searchUser = UserPrincipal.FindByIdentity(ctx, IdentityType.UserPrincipalName, userName)) 
       { 
        if (searchUser != null) 
        { 
         searchUser.ChangePassword(currentPassword, newPassword); 
         // searchUser.SetPassword(newPassword); 
         if (String.IsNullOrEmpty(searchUser.Guid.ToString())) 
         { 
          throw new Exception("Could not change password"); 
         } 
        } 
       } 
      } 
     } 
    } 

在此示例中,我通過UserPrincipalName搜索用戶。但我們並不僅限於此。我們還可以通過IdentityType.Guid等搜索用戶。

現在searchUser有兩個涉及密碼的方法。我提供了他們兩個。

//requires current and new password 
searchUser.ChangePassword(currentPassword, newPassword); 
//setting a password. Only requires new password. 
searchUser.SetPassword(newPassword); 

它最好使用SSL來設置或更改密碼。*

相關問題