gpt4 book ai didi

memory-leaks - System.DirectoryServices.AccountManagement.UserPrincipal.FindByIdentity 的奇怪问题

转载 作者:行者123 更新时间:2023-12-03 23:50:15 25 4
gpt4 key购买 nike

我们正在编写一个系统,允许用户通过我们内部网上的 Web 应用程序更改他们的帐户密码。

起初,一切似乎都很顺利。在我们的测试帐户的开发过程中,可以毫无问题地更改密码。

然而,当我们使系统上线时,我们开始遇到问题。以下是症状:

  • 起初,一切都很好。用户
    可以更改他们的密码。
  • 在某些
    点,出现以下错误
    UserPrincipal.FindByIdentity:
    “System.Runtime.InteropServices.COMException:
    认证机制是
    未知。 "
  • 从此,努力
    通过网络更改密码
    应用程序导致错误:
    “System.Runtime.InteropServices.COMException:
    服务器无法运行。 "
  • 如果我手动回收应用程序池,
    一切似乎都会自行修复,直到
    更多的错误开始发生......即,
    这个过程从头开始
    第一阶段。

  • 这是相关的代码片段:
        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);
    }
    }

    关于为什么会发生这种情况的任何线索?谷歌搜索没有找到任何真正有用的东西,MSDN 上的文档也没有。

    最佳答案

    我注意到的第一件事是您使用的是 UserPrincipal.FindByIdentity ,它是从 AuthenticablePrincipal 继承的,而 Principal 是从 MSDN entry 继承的。我之所以这么说是因为 Principal 类在 FindByIdentity 中有一个已知的内存泄漏。如果你看看这个 Gary Caldwell ,你会在底部注意到微软的 ojit_a 说了以下内容:

    This call has an unmanaged memory leak because the underlying implemenation uses DirectorySearcher and SearchResultsCollection but does not call dispose on the SearchResultsCollection as the document describes.



    我猜这是你的问题。内存泄漏导致 Application Pool 被填满并最终导致错误,直到 Application Pool 被重置并释放内存。

    当我们使用任何事件目录功能时,我们使用以下内容来完成用户密码的设置:
    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

    此外,如果您希望用户直接更改密码并且不想依赖他们的诚实,您可能需要考虑使用 LDAP 的 ChangePassword 函数,如下所示:
    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

    这会强制用户在更改为新密码之前知道先前的密码。

    我希望这有帮助,

    谢谢!

    关于memory-leaks - System.DirectoryServices.AccountManagement.UserPrincipal.FindByIdentity 的奇怪问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1883165/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com