假设我有Organisation
,其中有Student
个Organisation
。每个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>
我的问题是:
如何确保组织X不查询组织Y的数据(例如,通过在查询字符串中使用不属于此组织的不同ID登录)?
服务层是否应该添加额外的连接(Organisation
)以确保
当前登录的GetStudent(int id, int organisationId)
是唯一一个数据
问?如何从服务层获取当前用户?
我是否应该向{{1}}添加额外的参数并让控制器设置它?这似乎使我的服务膨胀。
我希望我已经解释得很好,如果我让自己感到困惑,请告诉我; - )
答案 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参数非常简单明了。