【发布时间】:2018-03-30 17:10:04
【问题描述】:
对于初学者来说,这里 (Temporary Session Based Claims in ASP.NET Core Identity) 和这里 (How to add claim to user dynamically?) 也有人问过这个问题,但是这两个问题都没有得到答案,所以我试图恢复它......
我正在创建一个多租户网络应用程序。用户登录,他们可以看到与自己公司相关的数据(但不能看到使用该应用程序的其他公司的数据)。由于特许经营集团拥有多个店面等,单个用户要求访问多个不同公司的情况并不少见,但在这种情况下,他们必须在登录时选择单个公司。
几乎所有数据查询都需要公司 ID 作为参数,因此我需要一种方便的方法来检查用户当前登录的公司。如果他们注销并登录到不同的公司,我需要查看不同的公司 ID。我想将它存储为我可以在会话期间看到的身份声明,但我不一定要将它存储到数据库中,因为它可能会随着每次登录而改变。
这是我的登录操作(基于标准 ASP.Net Core MVC 模板):
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Login(LoginViewModel model, string returnUrl = null)
{
ViewData["ReturnUrl"] = returnUrl;
if (ModelState.IsValid)
{
var result = await _signInManager.PasswordSignInAsync(model.Email, model.Password, model.RememberMe, lockoutOnFailure: false);
if (result.Succeeded)
{
// BEGIN CUSTOM CODE - Check which companies a user can access
IEnumerable<int> allCompanies = _myDbService.GetUserCompanies(model.Email);
if (allCompanies.Count() == 1)
{
// then they can only access one company - log them into it automatically.
// I need easy access to its ID with the User since it is used with almost every db query.
int companyID = allCompanies[0];
((ClaimsIdentity)User.Identity).AddClaim(new Claim("CompanyID", companyID.ToString())); // this shows as null on future controller actions.
Debug.WriteLine("Set breakpoint here to examine User"); // I see 1 claim (my custom claim) in the debugger, but it is not in the database yet.
// future controller actions show me 3 claims (nameidentifier, name, and security stamp) but User.Claims.First(c => c.Type == "CompanyID").Value throws error.
return RedirectToLocal(returnUrl);
}
else
{
// the user has access to several companies - make them choose one to complete login process
RedirectToAction("ChooseCompany", new { companyList = allCompanies });
}
// END CUSTOM CODE
}
// REMAINING CODE OMITTED FOR BREVITY
}
// If we got this far, something failed, redisplay form
return View(model);
}
所以我的问题是:为什么自定义声明不“坚持”以便在未来的控制器操作中可以看到?如果这是标准行为,为什么不将其保存到数据库中?有没有办法在不使用 AddSession() 的情况下在会话期间保持这个值?如果我将此作为声明来实现,我是否每次访问该值时都会往返于数据库?
【问题讨论】:
标签: c# asp.net-mvc asp.net-core-mvc asp.net-identity