【问题标题】:ASP.NET Identity - Reset a list of password asynchronouslyASP.NET Identity - 异步重置密码列表
【发布时间】:2023-03-19 18:45:01
【问题描述】:

我正在尝试在 Identity 2.1 中异步设置/重置大量用户密码。当我运行该进程时,它似乎与 ApplicationUserManager 混淆了。 (例如,即使我将新的 ID 和密码传递给新线程,我也会收到一条错误消息,提示它在未完成前一个线程时正在尝试更改用户。)由于当前上下文不在新线程中运行线程,我将 ApplicationUserManager 传递给执行实际重置的过程。当我如图所示(同步)运行它时,它工作正常,但每个用户需要 2-3 秒。这意味着运行 8-10 小时。 如果我可以在 ProcessUser 例程中实例化 ApplicationUserManager,我认为问题会消失,但到目前为止我还不能这样做,因为没有与页面相关的上下文。 有什么修复吗?

 Private Sub ProcessUsers()
    Dim mgr = Context.GetOwinContext().GetUserManager(Of ApplicationUserManager)() ' As New ApplicationUserManager()
    Dim ctx As New BCRContext()
    Dim ttl As Integer = 0
    Dim status As String

    ' Turn off password requirements for these temp passwords.
    mgr.PasswordValidator = New PasswordValidator() With {
        .RequireDigit = False,
        .RequireLowercase = False,
        .RequiredLength = 4,
        .RequireUppercase = False,
        .RequireNonLetterOrDigit = False
    }

    ' Get the list of user ID's and temp passswords 
    Dim qry As List(Of MyStuffDTO) = ctx.Database.SqlQuery(Of MyStuffDTO)("SELECT tmpPass.ID, Pass FROM tmpPass INNER JOIN AspNetUsers U ON U.ID=tmpPass.ID WHERE U.PasswordHash IS NULL ").ToList()

    Try

        For Each guy As MyStuffDTO In qry
            ttl += 1
            status = ttl & "/" & qry.Count & " - "

            ProcessUser(guy, mgr, status)

            'Dim task__1 = Task(Of String).Factory.StartNew(Function()
            '                                                   Return ProcessUser(guy, mgr, status)
            '                                               End Function
            '    )
        Next

        Debug.WriteLine("Done assigning tasks")

    Catch ex As Exception
        Logger.Error("Error processing guys", ex)
    End Try
End Sub

Private Function ProcessUser(guy As MyStuffDTO, mgr As ApplicationUserManager, status As String) As String
    Dim rslt As IdentityResult = Nothing
    Dim msg As String = ""

    Try
        If mgr.HasPassword(guy.ID) Then
            rslt = mgr.RemovePassword(guy.ID)
            If Not rslt.Succeeded Then
                msg = status & "Error removing password for ID:" & guy.ID & " - " & rslt.Errors(0)
                Debug.WriteLine(msg)
                Logger.Warn(msg)
                Return msg
            End If
        End If
        rslt = mgr.AddPassword(guy.ID, guy.Pass)
        If Not rslt.Succeeded Then
            msg = status & "Error setting password for ID:" & guy.ID & " - " & rslt.Errors(0)
            Debug.WriteLine(msg)
            Logger.Warn(msg)
        Else
            msg = status & "Succeeded for ID:" & guy.ID
            Debug.WriteLine(msg)
        End If

    Catch ex As Exception
        msg = "Error progessing guy " & guy.ID
        Logger.Error("Error progessing guy " & guy.ID, ex)
        Return msg & " - " & ex.Message
    End Try

    Return msg

End Function

Public Class MyStuffDTO
    Public Property ID As String
    Public Property Pass As String
End Class

【问题讨论】:

    标签: asp.net vb.net asynchronous asp.net-identity


    【解决方案1】:

    我的 VB 有点粗糙,所以我将在 C# 中发布我的示例

    从 OwinContext 获取 UserManager 后,您可以像这样循环用户...

    var user = await UserManager.FindByNameAsync(model.Email);
    UserManager.GeneratePasswordResetTokenAsync(user.Id).ContinueWith((t) => { UserManager.ResetPasswordAsync(user.Id, t.Result, "NEW PASSWORD"); });
    

    【讨论】:

    • 您无需生成令牌即可更改密码。只需使用userManager.RemovePassword(userId); userManager.AddPassword(userId, newPassword);
    • 谢谢。问题是我似乎无法从新线程中生成用户管理器,并将用户管理器作为引用变量传递会崩溃,说它一次只能使用一个名称。
    猜你喜欢
    • 2013-10-31
    • 2014-04-14
    • 2014-07-22
    • 2017-01-29
    • 1970-01-01
    • 2016-05-03
    • 2015-04-28
    • 2017-10-20
    相关资源
    最近更新 更多