ASP.NET 身份更改密码注销用户

ASP.NET Identity Changing Password Signs User Out

我对 ASP.NET 身份提供商有疑问。我从 Visual Studio 2019 附带的默认模板开始,目标是 .NET 4.7.2 WebForms。

在更改密码页面上,身份提供商似乎没有更新 .AspNet.ApplicationCookie 以反映新的 SecurityStamp。我可以在 Fiddler 中看到 ASP.NET 正在发送一个 302 以重定向回 Manage.aspx 页面,并且它正在发送一个身份验证 cookie,大概应该反映由密码产生的新 SecurityStamp改变,除了它没有。因此,用户在更改密码或 2FA 后会立即退出应用程序,因为我已将 validateInterval 设置为 TimeSpan.Zero。如果我将它设置为另一个值,则用户的 cookie 在该值之后将变为无效,无论 cookie 应该具有的实际年龄如何。

app.UseCookieAuthentication(New CookieAuthenticationOptions() With {
            .AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
            .ExpireTimeSpan = TimeSpan.FromDays(14),
            .SlidingExpiration = True,
            .Provider = New CookieAuthenticationProvider() With {
                .OnValidateIdentity = SecurityStampValidator.OnValidateIdentity(Of ApplicationUserManager, ApplicationUser)(
                    validateInterval:=TimeSpan.Zero,
                    regenerateIdentity:=Function(manager, user) user.GenerateUserIdentityAsync(manager))},
            .LoginPath = New PathString("/Account/Login")})

这里是更改密码页面中的相关代码:

Protected Sub ChangePassword_Click(sender As Object, e As EventArgs)
    If IsValid Then
        Dim manager = Context.GetOwinContext().GetUserManager(Of ApplicationUserManager)()
        Dim signInManager = Context.GetOwinContext().Get(Of ApplicationSignInManager)()
        Dim result As IdentityResult = manager.ChangePassword(User.Identity.GetUserId(), CurrentPassword.Text, NewPassword.Text)
        If result.Succeeded Then
            Dim userInfo = manager.FindById(User.Identity.GetUserId())
            signInManager.SignIn(userInfo, isPersistent:=False, rememberBrowser:=False)
            Response.Redirect("~/Profile/Manage?m=ChangePwdSuccess")
        Else
            AddErrors(result)
        End If
    End If
End Sub

原来你需要注销用户然后重新登录:

Protected Sub ChangePassword_Click(sender As Object, e As EventArgs)
    If IsValid Then
        Dim userManager = Context.GetOwinContext().GetUserManager(Of ApplicationUserManager)()
        Dim signInManager = Context.GetOwinContext().Get(Of ApplicationSignInManager)()
        Dim authenticateResult = Context.GetOwinContext().Authentication.AuthenticateAsync(DefaultAuthenticationTypes.ApplicationCookie).GetAwaiter.GetResult()
        Dim accountChangeResult As IdentityResult = userManager.ChangePassword(User.Identity.GetUserId(), CurrentPassword.Text, NewPassword.Text)
        If accountChangeResult.Succeeded Then
            Context.GetOwinContext().Authentication.SignOut(DefaultAuthenticationTypes.ApplicationCookie)
            Dim userInfo = userManager.FindById(User.Identity.GetUserId())
            signInManager.SignIn(userInfo, isPersistent:=authenticateResult.Properties.IsPersistent, rememberBrowser:=False)
            Response.Redirect("~/Profile/Manage?m=ChangePwdSuccess")
        Else
            AddErrors(accountChangeResult)
        End If
    End If
End Sub