Ответ 1
Прежде всего я замечаю, что вы используете UserPrincipal.FindByIdentity, который унаследован от AuthenticablePrincipal, который наследуется от Principal. Я говорю все это, потому что класс Principal
имеет известную утечку памяти в FindByIdentity
. Если вы посмотрите на запись MSDN, вы заметите внизу, что Гэри Колдуэлл от Microsoft сказал следующее:
Этот вызов имеет неуправляемую утечку памяти потому что базовое воплощение использует DirectorySearcher и SearchResultsCollection, но не вызывать на SearchResultsCollection как документ описывает.
Я бы предположил, что это твоя проблема. Утечка памяти заставляет пул приложений заполнять и, наконец, вызывать ошибки, пока пул приложений не будет reset и память будет удалена.
Когда мы используем любые активные функции каталогов, для выполнения настройки пароля пользователя мы используем следующее:
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
Кроме того, если вы хотите, чтобы пользователи напрямую меняли пароли, и вы не хотите полагаться на их честность, вам может потребоваться использовать функцию 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
Это заставляет пользователя знать предыдущий пароль перед тем, как перейти на новый.
Я надеюсь, что это поможет,