gpt4 book ai didi

c# - 如何授权用户使用 asp.net Identity 2.0 仅查看自己的记录

转载 作者:行者123 更新时间:2023-12-05 01:01:26 25 4
gpt4 key购买 nike

对于这样一个笼统的问题,必须有一个简单的解决方案,所以我为我的无知预先道歉:

我有一个多用户 Web 应用程序(带有 EF6 的 Asp.net MVC5)。允许用户查看和/或修改存储在多个相关表(Company、Csearch、Candidate)中的相关数据。 (有关更多详细信息,请参见下文)。他们不应该看到任何其他数据(例如通过篡改 URL)。

我使用 Asp.net Identity 2.0 进行身份验证,也希望将其用于上述授权。用户数据存储在标准 AspNetUser 表中。我只为 Identity 和我的业务表使用一个上下文。

我想我必须使用角色或声明来解决这个问题,但我找不到任何关于如何做到这一点的指导。谁能指出我正确的方向?

我目前已经通过向 CompanyController 添加一个 LINQ 条件来解决它(对于公司模型),但这似乎不是解决问题的一种非常安全和正确的方法。

public ActionResult Index(int? id, int? csearchid)
{
var companies = db.Companies
.OrderBy(i => i.CompanyName)
.Where(t => t.UserName == User.Identity.Name);
return View(companies);

我的 DataModel 很简单,我使用 Visual Studio 2017 搭建了它首先通过EF6代码我构建了一个关系数据模型,大致如下:

一个公司可以有多个搜索(一对多)。每个搜索可以有多个候选(一对多)。一个公司可以有多个用户登录。用户保存在由 ASP.Net Identity 生成的 AspNetUsers 表中。

我的公司模型如下所示:

public class Company
{
public int CompanyID { get; set; }

// Link naar de Userid in Identity: AspNetUsers.Id
[Display(Name = "Username")]
public string UserName { get; set; }
public string CompanyName { get; set;}
public string CompanyContactName { get; set; }
[DataType(DataType.EmailAddress)]
public string CompanyEmail { get; set; }
public string CompanyPhone { get; set; }

[Timestamp]
public byte[] RowVersion { get; set; }

//One to Many Navigatie links
public virtual ICollection<Csearch> Csearches { get; set; }

最佳答案

一旦用户被识别,您可以确保用户只能访问自己的数据。您不能为此使用角色,因为这只会定义访问级别。但您可以使用声明。

开箱即用有一个关注点分离。保持这种分离。您不应该直接查询 Identity 表。为此使用 userManager。另外从不使用 Identity 对象作为 ViewModel。你可能会暴露比你想要的更多。如果你保持这种分离,你会发现它实际上要容易得多。

身份上下文包含识别用户的所有数据,业务上下文包含所有业务信息,包括用户信息。您可能认为这是多余的,但登录用户与业务用户确实没有任何共同之处。登录电子邮件地址可能与 business.user.emailaddress 不同(这两种情况下的电子邮件地址是什么意思?)。还要考虑让用户无法登录(不再)的可能性。

根据经验,请始终考虑信息是身份的一部分还是业务的一部分。

什么时候需要ApplicationUser?仅适用于当前用户或管理用户时。查询用户时,请始终使用 business.user。因为那里应该提供您需要的所有信息。

对于当前用户,使用您需要的信息添加声明。声明的优点是您不必在每次调用时都查询数据库来检索此信息,例如相应的 UserId 和(显示)UserName。

如何添加声明

您可以通过在 AspNetUserClaims 表中添加一行来向用户添加声明,而无需扩展 ApplicationUser 类。比如:

userManager.AddClaim(id, new Claim("UserId", UserId));

登录后,声明将自动添加到 ClaimsIdentity。

您还可以为扩展 ApplicationUser 的属性添加声明:

public class ApplicationUser : IdentityUser
{
public int UserId { get; set; }

public string DisplayUserName { get; set; }

public async Task<ClaimsIdentity> GenerateUserIdentityAsync(UserManager<ApplicationUser> manager)
{
// Note the authenticationType must match the one defined in CookieAuthenticationOptions.AuthenticationType
var userIdentity = await manager.CreateIdentityAsync(this, DefaultAuthenticationTypes.ApplicationCookie);

// Add custom user claims here
userIdentity.AddClaim(new Claim("UserId", UserId));
userIdentity.AddClaim(new Claim("DisplayUserName", DisplayUserName));

return userIdentity;
}
}

如何解读声明

在 Controller 中,您可以使用如下代码读取声明:

var user = (System.Security.Claims.ClaimsIdentity)User.Identity;
var userId = user.FindFirstValue("UserId");

您可以在查询中使用 userId 来过滤当前用户的数据,甚至可以使用 business.users 作为检索数据的唯一条目。像 db.Users(u => u.Id == userId).Companies.ToList();

请注意,代码只是一个示例。我没有全部测试。这只是给你一个想法。如果有不清楚的地方,请告诉我。

关于c# - 如何授权用户使用 asp.net Identity 2.0 仅查看自己的记录,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44783744/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com