在默认的 ASP.Net MVC 模板中,为什么用户每次更改某些内容时都会重新登录?
In the default ASP.Net MVC template, why does the user get re-signed in every time they change something?
所以我使用默认的 ASP.Net MVC 模板并从项目中整理出我不需要的东西。如果用户更改密码或 phone 号码等内容,他们会再次登录。
例如,在 ManagerController.cs 文件中,我一直看到类似
的内容
//
// POST: /Manage/ChangePassword
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<ActionResult> ChangePassword(ChangePasswordViewModel model)
{
if (!ModelState.IsValid)
{
return View(model);
}
var result = await UserManager.ChangePasswordAsync(User.Identity.GetUserId<int>(), model.OldPassword, model.NewPassword);
if (result.Succeeded)
{
var user = await UserManager.FindByIdAsync(User.Identity.GetUserId<int>());
if (user != null)
{
await SignInManager.SignInAsync(user, isPersistent: false, rememberBrowser: false);
}
return RedirectToAction("Index", new { Message = ManageMessageId.ChangePasswordSuccess });
}
AddErrors(result);
return View(model);
}
该代码的相关部分是
var user = await UserManager.FindByIdAsync(User.Identity.GetUserId<int>());
if (user != null)
{
await SignInManager.SignInAsync(user, isPersistent: false, rememberBrowser: false);
}
这段重复代码的目的是什么?我需要它吗?顺便说一句,我正在删除 2 因素授权和 phone 验证。
Do I need it?
是(见下文)
What is the purpose of this repetitive code?
假设您使用的是 Identity,那么通常需要重新加载所有声明。我不确定任何声明是否有任何密码哈希或种子(如果有,那么肯定)但是任何角色更改或声明更改对于以后的代码(可能在视图中)正确验证用户是必要的。
使用 SignInManager.SignIn
重新登录用户应该会导致重新生成用户身份验证 cookie(如果使用默认的应用程序 cookie),并随之重新生成用户的安全标记。每次用户角色、声明、登录或存储在 ClaimsIdentity (User.Identity
) 中的任何其他内容发生更改时,都应更改安全标记。否则,用户将使用与数据库不匹配的过时 cookie(它是序列化的 ClaimsIdentity)。如果发生这种情况,他们可能拥有被删除的角色,或者没有被添加的角色。
还有其他方法可以重新生成安全戳,这实际上是所有需要的,因为带有无效安全戳的身份验证 cookie 将简单地重新生成以包含正确的信息,而不是拒绝未经授权的请求。但是,这就是默认情况下的完成方式,可能就是所需要的。
所以我使用默认的 ASP.Net MVC 模板并从项目中整理出我不需要的东西。如果用户更改密码或 phone 号码等内容,他们会再次登录。
例如,在 ManagerController.cs 文件中,我一直看到类似
的内容 //
// POST: /Manage/ChangePassword
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<ActionResult> ChangePassword(ChangePasswordViewModel model)
{
if (!ModelState.IsValid)
{
return View(model);
}
var result = await UserManager.ChangePasswordAsync(User.Identity.GetUserId<int>(), model.OldPassword, model.NewPassword);
if (result.Succeeded)
{
var user = await UserManager.FindByIdAsync(User.Identity.GetUserId<int>());
if (user != null)
{
await SignInManager.SignInAsync(user, isPersistent: false, rememberBrowser: false);
}
return RedirectToAction("Index", new { Message = ManageMessageId.ChangePasswordSuccess });
}
AddErrors(result);
return View(model);
}
该代码的相关部分是
var user = await UserManager.FindByIdAsync(User.Identity.GetUserId<int>());
if (user != null)
{
await SignInManager.SignInAsync(user, isPersistent: false, rememberBrowser: false);
}
这段重复代码的目的是什么?我需要它吗?顺便说一句,我正在删除 2 因素授权和 phone 验证。
Do I need it?
是(见下文)
What is the purpose of this repetitive code?
假设您使用的是 Identity,那么通常需要重新加载所有声明。我不确定任何声明是否有任何密码哈希或种子(如果有,那么肯定)但是任何角色更改或声明更改对于以后的代码(可能在视图中)正确验证用户是必要的。
使用 SignInManager.SignIn
重新登录用户应该会导致重新生成用户身份验证 cookie(如果使用默认的应用程序 cookie),并随之重新生成用户的安全标记。每次用户角色、声明、登录或存储在 ClaimsIdentity (User.Identity
) 中的任何其他内容发生更改时,都应更改安全标记。否则,用户将使用与数据库不匹配的过时 cookie(它是序列化的 ClaimsIdentity)。如果发生这种情况,他们可能拥有被删除的角色,或者没有被添加的角色。
还有其他方法可以重新生成安全戳,这实际上是所有需要的,因为带有无效安全戳的身份验证 cookie 将简单地重新生成以包含正确的信息,而不是拒绝未经授权的请求。但是,这就是默认情况下的完成方式,可能就是所需要的。