确保用户X不查询用户Y的数据

时间:2014-06-30 06:04:24

标签: c# entity-framework asp.net-identity

假设我有Organisation,其中有StudentOrganisation。每个Student都有一个登录信息,其中显示了相关Student的列表。

查看/students/edit/<id>的列表时,我可以点击其中一个来编辑它们。这会将我带到一个页面,让我们说public class StudentService : IStudentService { private readonly IRepository _repository; // injected in constructor public Student GetStudent(int id) { return _repository.Get<Student>(x => x.Id = id); } }

查询此页面的视图可以从我的服务层获取学生:

&& x.OrganisationId == <organisation id>

我的问题是:

  1. 如何确保组织X不查询组织Y的数据(例如,通过在查询字符串中使用不属于此组织的不同ID登录)?

  2. 服务层是否应该添加额外的连接(Organisation)以确保 当前登录的GetStudent(int id, int organisationId)是唯一一个数据 问?如何从服务层获取当前用户?

  3. 我是否应该向{{1}}添加额外的参数并让控制器设置它?这似乎使我的服务膨胀。

  4. 我希望我已经解释得很好,如果我让自己感到困惑,请告诉我; - )

3 个答案:

答案 0 :(得分:2)

我建议您的服务了解当前经过身份验证的用户。这将允许您在每个查询中包含类似于下面的限制Where子句,以防止用户看到其他组织的学生

 private Student GetStudent(int id) {
      return _repository
        .Get<Student>(x => x.Id = id)
        .Where(s => s.OrganisationId == _currentUser.OrganisationId)
        .FirstOrDefault();
 }

答案 1 :(得分:1)

我去年开发了一个类似场景的网络应用程序。我所做的是在我的每个存储库中创建一个名为GetFilteredQueryable的方法,该方法将当前登录用户的用户名作为参数(我们更喜欢使用电子邮件地址,但实际上任何工作都有效)。例如,在搜索学生记录时,我会执行以下操作:

IEnumerable<Student> GetStudentsHavingSubject(string subjectCode, string curUser)
{
    var Students = this.GetFilteredQueryable<Student>(CurUser);
    Students = Students.Where(x => x.subjects.Any(y=>y.SubjectCode == subjectCode));
    return Students.AsEnumerable();
}

IQueryable<Student> GetFilteredQueryable(curUser)
{
    //you could do any other checks in here too, like user level, permissions, etc.
    return DB.Students.Where(x => x.Organization.Users.Any(y=>y.UserName == curUser));
}

答案 2 :(得分:0)

我建议只为organisationId添加一个参数。编写方法总是想象为您的方法编写测试。如果写测试很尴尬,你应该重构你的方法。

传递organisationId参数非常简单明了。