在我们的应用程序中,我们有角色,每个角色都有许多功能。我们的目标是在功能级别而不是角色级别控制访问,尽可能减少对数据库的访问。
这是我们的工作:
1) 在登录时,我们创建一个 UserCredentials 对象,其中包含用户可以访问的所有功能(基于其角色)。它是用户有权访问的所有角色中包含的所有功能的“独特”。然后我们将这个 UserCredentials 存储在 session 中。
2)为了限制对控制器或动作的访问,我们实现了一个继承 AuthorizeAttribute 的属性,我们使用如下:
[Secure(Functionalities="Xyz.View,Xyz.Save")]
public ActionResult SomeAction(...){ ... }
请注意,没有数据库调用,我们所做的只是检查“Xyz.View”是否在存储在 UserCredentials 中的功能列表中。
3) 有时我们需要从操作内部访问凭据,因此我们创建了另一个 ActionFilter(全局),如果他找到名为“凭据”的参数,它将为您在操作参数中注入凭据,例如:
public ActionResult SomeAction(UserCredentials credentials, int otherParameters)
{
// "credentials" is populated by the global action filter
}
您可以使用它来根据用户角色或功能显示不同的视图。
4) 另一种情况是当我们需要根据用户角色或功能隐藏部分视图时。为此,我们创建了一个具有 UserCredentials 属性的 BaseViewModel。此属性还由另一个在执行操作后运行的全局 ActionFilter 填充。如果模型继承 BaseViewModel,则过滤器填充 UserCredentials 属性。我们可以这样做:
@if(Model.UserCredentials.IsInRole("X")){
<div>Some content</div>
}
或
@if(Model.UserCredentials.HasAccessTo("Xyz.Save")){
<button>Save</button>
}
希望对你有帮助。