我正在从我的 .net 应用程序(asp.net VB .net 4.0)连接到 DMZ 中的 Microsoft Active Directory 服务器。我需要在名为“SingleCustomerAccount”的组织单元中创建一个新的“inetorgperson”。
我不得不使用 System.DirectoryServices.Protocols 命名空间来完成所有工作,因为 ADSI 类(System.DirectoryServices 命名空间)无法在 DMZ 中正常工作。
无论如何,在 Windows Server 2003 R2 上连接到 Active Directory 工作正常;但是,我们正在 Windows Server 2008 R2(2008r2 在本机模式下用于林和域)上针对 Active Directory 运行测试以进行升级。
我现有的创建用户的代码不起作用。
System.DirectoryServices.Protocols.DirectoryOperationException:服务器无法处理目录请求。 在 System.DirectoryServices.Protocols.LdapConnection.ConstructResponse(Int32 messageId,LdapOperation 操作,ResultAll resultType,TimeSpan requestTimeOut,布尔异常OnTimeOut) 在 System.DirectoryServices.Protocols.LdapConnection.SendRequest(DirectoryRequest 请求,TimeSpan requestTimeout) 在 System.DirectoryServices.Protocols.LdapConnection.SendRequest(DirectoryRequest 请求) 在 Salford.LDAP.LDAPUser.SaveNewToDirectory(String UsersFirstPassword) 在 C:\Projects\SCA\App_Code\SCA\LDAPUser.vb:line 1059 在 SCA.Web.Service.CitizenService.CreateNewAccount(字符串用户名,字符串标题,字符串名字,字符串姓氏,字符串街道,字符串城市,字符串县,字符串邮政编码,字符串电子邮件地址,字符串 HomeTel,字符串 MobileTel,字符串 UPRN,字符串 SpinID, C:\Projects\SCA\App_Code\CitizenService.vb:line 255 中的 Int16 AccountLevel)
我发现当我删除添加密码属性的代码时,会创建用户,但只是没有密码。所以错误代码是我添加密码的地方。但是在 2003 年到 2008 年之间发生了哪些变化,导致它无法正常工作?
这是我的代码。
Using ldapConn As New LdapConnection(New LdapDirectoryIdentifier(LDAPServerAddress), credential)
ldapConn.SessionOptions.ProtocolVersion = 3
ldapConn.SessionOptions.Signing = Not _UseSecureConnection
ldapConn.SessionOptions.Sealing = Not _UseSecureConnection
ldapConn.SessionOptions.SecureSocketLayer = _UseSecureConnection
If _UseSecureConnection Then
ldapConn.SessionOptions.VerifyServerCertificate = New VerifyServerCertificateCallback(AddressOf ServerCallback)
End If
ldapConn.AuthType = AuthType.Negotiate
ldapConn.Bind()
Dim DistinguishedName As String = String.Format("CN={0},OU={1},{2}", Me.AccountName, Me.OrgUnit, Me.DCSuffix)
' Save this distinguished name to the local object; so that the group memberships addition works in a minute.
Me._DistinguishedName = DistinguishedName
Dim addRequest As New AddRequest(DistinguishedName, Me.LDAPUserObjectType)
'' Add an AccountName attribute
addRequest.Attributes.Add(New DirectoryAttribute(GetLDAPSchemaMapping(LDAPUserProperties.AccountName), AccountName))
'' Look in any derived classes, if they want any attributes adding as part of this save operation.
'' Hint: Derived classes will override the "GetDirectoryAttributesForAddNewRequest" function and return a list of anything they want adding
'' to the AD at the time of creation.
If Not GetDirectoryAttributesForAddNewRequest() Is Nothing Then
For Each kvp As KeyValuePair(Of String, String) In GetDirectoryAttributesForAddNewRequest()
addRequest.Attributes.Add(New DirectoryAttribute(kvp.Key, kvp.Value))
Next
End If
'' Hash up the password into a Unicode byte array and send this as the requried initial password.
addRequest.Attributes.Add(New DirectoryAttribute("unicodePwd", GetPasswordData(UsersFirstPassword)))
' Execute the request on the directory server.
Dim addResponse As DirectoryResponse = ldapConn.SendRequest(addRequest)
' Need to return the GUID, need to search against the ldap server:
Dim request As New SearchRequest(String.Format("OU={0},{1}", Me.OrgUnit, Me.DCSuffix), "(&(objectCategory=" & Me.LDAPUserObjectType & ")(sAMAccountName=" & Me.AccountName & "))", System.DirectoryServices.Protocols.SearchScope.Subtree)
Dim searchResponse As SearchResponse = DirectCast(ldapConn.SendRequest(request), SearchResponse)
returnedGuid = DirectCast(searchResponse.Entries(0).Attributes("objectGuid").Item(0), Byte())
' Set up the search request object so we can do searches now based on this new user:
Dim rq As SearchRequest = BuildLdapSearchRequest("sAMAccountName", Me.AccountName)
' ** Send the query to the LDAP server, and save the response into the private _SearchResponse object **
_SearchResponse = DirectCast(ldapConn.SendRequest(rq), SearchResponse)
End Using
此调用的 _useSecureConnection 为 false - 绑定工作正常。就像我说过的,当我注释掉这一行时,它会起作用:
addRequest.Attributes.Add(New DirectoryAttribute("unicodePwd", GetPasswordData(UsersFirstPassword)))
为完整起见,GetPasswordData 方法如下所示。
''' <summary>
''' Returns a unicode-encoded byte array based on the incoming password string.
''' </summary>
''' <param name="password">The password to turn into a byte array</param>
Public Function GetPasswordData(ByVal password As String) As Byte()
Dim formattedPassword As String
formattedPassword = String.Format("""{0}""", password)
Return Encoding.Unicode.GetBytes(formattedPassword)
End Function
我感谢任何见解...
问候 bgs264