13 directoryservices memory-leaks ldap active-directory account-management
我们正在编写一个允许用户通过Intranet上的Web应用程序更改其帐户密码的系统.
起初,一切似乎都在顺利进行.在开发期间,我们的测试帐户的密码可以毫无问题地更改.
然而,当我们制作系统时,我们开始遇到问题.以下是症状:
这是相关的代码片段:
private static PrincipalContext CreateManagementContext() {
return new PrincipalContext(
ContextType.Domain,
ActiveDirectoryDomain,
ActiveDirectoryManagementAccountName,
ActiveDirectoryManagementAccountPassword);
}
private static void ChangeActiveDirectoryPasword(string username, string password) {
if (username == null) throw new ArgumentNullException("username");
if (password == null) throw new ArgumentNullException("password");
using (var context = CreateManagementContext())
using (var user = UserPrincipal.FindByIdentity(context, IdentityType.SamAccountName, username)) {
user.SetPassword(password);
}
}
Run Code Online (Sandbox Code Playgroud)
关于为什么会发生这种情况的任何线索?谷歌搜索没有提供任何真正有用的信息,MSDN上的文档也没有.
Sco*_*ott 11
我注意到的第一件事是你正在使用UserPrincipal.FindByIdentity,它继承自Principal继承自AuthenticablePrincipal.我说这一切都是因为这个类中有一个已知的内存泄漏.如果您查看此MSDN条目,您会在底部注意到Microsoft的Gary Caldwell说:Principal
FindByIdentity
此调用具有非托管内存泄漏,因为底层实现使用DirectorySearcher和SearchResultsCollection,但不会像文档描述那样在SearchResultsCollection上调用dispose.
我猜这是你的问题.内存泄漏导致应用程序池填满并最终导致错误,直到重置应用程序池并释放内存.
当我们使用任何活动目录函数时,我们使用以下内容来完成用户密码的设置:
Public Shared Function GetUserAccount(ByVal username As String) As DirectoryEntry
Dim rootPath As String = GetRootPath()
Using objRootEntry As New DirectoryEntry(rootPath)
Using objAdSearcher As New DirectorySearcher(objRootEntry)
objAdSearcher.Filter = "(&(objectClass=user)(samAccountName=" & username & "))"
Dim objResult As SearchResult = objAdSearcher.FindOne()
If objResult IsNot Nothing Then Return objResult.GetDirectoryEntry()
End Using
End Using
Return Nothing
End Function
Public Shared Sub SetPassword(ByVal username As String, ByVal newPassword As String)
Using objUser As DirectoryEntry = GetUserAccount(username)
If objUser Is Nothing Then Throw New UserNotFoundException(username)
Try
objUser.Invoke("SetPassword", newPassword)
objUser.CommitChanges()
Catch ex As Exception
Throw New Exception("Could not change password for " & username & ".", ex)
End Try
End Using
End Sub
Run Code Online (Sandbox Code Playgroud)
此外,如果您希望用户直接更改密码而您不想依赖他们的诚实,您可能需要考虑使用ChangePassword
LDAP 的功能,如下所示:
Public Shared Sub ChangePassword(ByVal username As String, ByVal oldPassword As String, ByVal newPassword As String)
Using objUser As DirectoryEntry = GetUserAccount(username)
If objUser Is Nothing Then Throw New UserNotFoundException(username)
Try
objUser.Invoke("ChangePassword", oldPassword, newPassword)
objUser.CommitChanges()
Catch ex As TargetInvocationException
Throw New Exception("Could not change password for " & username & ".", ex)
End Try
End Using
End Sub
Run Code Online (Sandbox Code Playgroud)
这会强制用户在更改为新密码之前知道先前的密码.
我希望这有帮助,
归档时间: |
|
查看次数: |
5581 次 |
最近记录: |