我可以使用[Authorize(Roles=...)]
限制整个控制器操作访问权限,但是,如果我想让用户例如查看他们自己部门中其他用户的数据(仅限),那该怎么办呢。
具体我的意思是当我向用户提供另一个用户的详细信息时,URL将如下所示:
myapp.com/user/details/45
他们可以很容易地将45
编辑为他们想要的任何内容。如果请求的用户不属于他们自己的公司(他们的公司目前在他们的会话中但可以更改),我想限制访问权限。
我可以看到一些不同的方法来做到这一点,但我只是想知道每个人的偏好是基于经验。以下是一些选项:
1.通过编辑路由来改变访问方式。 myapp.com/Company/4/User/4' where 4 is a psudoID which references an actual ID internally.
2.
myapp.com/OurCompany/User/4'<相同,但我们公司的控制器,而不是一般公司。
3.通过检查所请求的用户是否在同一公司内部来检查它:`myapp.com/User/42345'。我的问题是必须针对每种请求(用户,产品,相关公司)进行定制。但这就是我现在正在看的。
EntityFramework实际上有权引用当前用户的公司成员,因为当他们登录时,我获得他们公司的条目并将其存储在会话中。这样可以轻松访问公司成员,如下所示:
SessionHandler.UserSession.CompanyTable.UserTable.Where(e=> e.UserID == id).FirstOrDefault();
对于那些不了解EF的人来说,这似乎很奇怪,但基本上子表UserTable
是由CompanyTable的外键引用的所有用户的子集,它确实返回了正确的实体集。这样做的问题是以这种方式更新条目实际上更新了SESSION中的条目,但没有更新DATABASE中的条目,DATABASE是真正的集市,因为这意味着登录用户似乎可以对数据库进行更改但实际上它们只是被保存到会话中。 (盯着数据库whist进行这些更改确认了它,注销并登录没有保存,但db.SaveChanges()
被正确调用,只是没有进行任何更改)
答案 0 :(得分:2)
首先,为了对一切美好和圣洁的爱,不要把它放在会议中。无论如何,这个会话都不应该用于此,而且这是最糟糕的代码味道。
您所谈论的是对象级权限。正确的方法是使用当前登录用户的某些识别因子来限制查询。您的实体需要这项工作的“所有权”概念。换句话说,他们需要一个“拥有”该特定实例的其他实体的外键。由于您希望按部门限制,这意味着您的所有用户都需要由部门拥有。然后,对于这样的情况,您可以执行以下操作:
git branch bugfix/xyz; edit...; git push origin bugfix/xyz;
此处db.Users.Where(m => m.DepartmentId == user.DepartmentId)
这里是当前登录用户的实例。通过以这种方式查询,用户可用的实体子集受到用户本身的限制。这意味着尝试访问id超出该集合的URL自然会产生404. 404实际上是最好的,因为即使它是基于授权的,返回403也会让你知道有什么东西 - 你就可以不能访问它。对于黑客来说,这种信息只是成功的一半。返回的404将为您提供零信息。它可能不存在,或者你可能无法使用。