- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
对于这样一个笼统的问题,必须有一个简单的解决方案,所以我为我的无知预先道歉:
我有一个多用户 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/
#include using namespace std; class C{ private: int value; public: C(){ value = 0;
这个问题已经有答案了: What is the difference between char a[] = ?string?; and char *p = ?string?;? (8 个回答) 已关闭
关闭。此题需要details or clarity 。目前不接受答案。 想要改进这个问题吗?通过 editing this post 添加详细信息并澄清问题. 已关闭 7 年前。 此帖子已于 8 个月
除了调试之外,是否有任何针对 c、c++ 或 c# 的测试工具,其工作原理类似于将独立函数复制粘贴到某个文本框,然后在其他文本框中输入参数? 最佳答案 也许您会考虑单元测试。我推荐你谷歌测试和谷歌模拟
我想在第二台显示器中移动一个窗口 (HWND)。问题是我尝试了很多方法,例如将分辨率加倍或输入负值,但它永远无法将窗口放在我的第二台显示器上。 关于如何在 C/C++/c# 中执行此操作的任何线索 最
我正在寻找 C/C++/C## 中不同类型 DES 的现有实现。我的运行平台是Windows XP/Vista/7。 我正在尝试编写一个 C# 程序,它将使用 DES 算法进行加密和解密。我需要一些实
很难说出这里要问什么。这个问题模棱两可、含糊不清、不完整、过于宽泛或夸夸其谈,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开,visit the help center . 关闭 1
有没有办法强制将另一个 窗口置于顶部? 不是应用程序的窗口,而是另一个已经在系统上运行的窗口。 (Windows, C/C++/C#) 最佳答案 SetWindowPos(that_window_ha
假设您可以在 C/C++ 或 Csharp 之间做出选择,并且您打算在 Windows 和 Linux 服务器上运行同一服务器的多个实例,那么构建套接字服务器应用程序的最明智选择是什么? 最佳答案 如
你们能告诉我它们之间的区别吗? 顺便问一下,有什么叫C++库或C库的吗? 最佳答案 C++ 标准库 和 C 标准库 是 C++ 和 C 标准定义的库,提供给 C++ 和 C 程序使用。那是那些词的共同
下面的测试代码,我将输出信息放在注释中。我使用的是 gcc 4.8.5 和 Centos 7.2。 #include #include class C { public:
很难说出这里问的是什么。这个问题是含糊的、模糊的、不完整的、过于宽泛的或修辞性的,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开它,visit the help center 。 已关
我的客户将使用名为 annoucement 的结构/类与客户通信。我想我会用 C++ 编写服务器。会有很多不同的类继承annoucement。我的问题是通过网络将这些类发送给客户端 我想也许我应该使用
我在 C# 中有以下函数: public Matrix ConcatDescriptors(IList> descriptors) { int cols = descriptors[0].Co
我有一个项目要编写一个函数来对某些数据执行某些操作。我可以用 C/C++ 编写代码,但我不想与雇主共享该函数的代码。相反,我只想让他有权在他自己的代码中调用该函数。是否可以?我想到了这两种方法 - 在
我使用的是编写糟糕的第 3 方 (C/C++) Api。我从托管代码(C++/CLI)中使用它。有时会出现“访问冲突错误”。这使整个应用程序崩溃。我知道我无法处理这些错误[如果指针访问非法内存位置等,
关闭。这个问题不符合Stack Overflow guidelines .它目前不接受答案。 我们不允许提问寻求书籍、工具、软件库等的推荐。您可以编辑问题,以便用事实和引用来回答。 关闭 7 年前。
已关闭。此问题不符合Stack Overflow guidelines 。目前不接受答案。 要求我们推荐或查找工具、库或最喜欢的场外资源的问题对于 Stack Overflow 来说是偏离主题的,因为
我有一些 C 代码,将使用 P/Invoke 从 C# 调用。我正在尝试为这个 C 函数定义一个 C# 等效项。 SomeData* DoSomething(); struct SomeData {
这个问题已经有答案了: Why are these constructs using pre and post-increment undefined behavior? (14 个回答) 已关闭 6
我是一名优秀的程序员,十分优秀!