【发布时间】:2015-10-08 14:58:03
【问题描述】:
我目前面临的情况是,我正在使用特定的授权属性装饰我的 HttpPost 控制器操作方法,并在我的 HttpGet 中指定相同的规则以确保某些功能在我的视图中不可用。
是否有最佳实践或更好的解决方案,以便我可以在一个地方指定实际的业务规则以启用 DRY,并且不会陷入代码爆炸的情况,即每个规则都有一个特定的 Authorize 属性..
我现在的情况是这样的:
public class MyController
{
[HttpGet]
public ActionResult List()
{
// This action is responsible for showing the list of records. Each record
// can potentially have a delete link but this is only shown for Administrators
var viewModel = new MyViewModel()
{
CanDeleteRecordRole = Role.Administrator, // Duplicated rule here
// other properties
}
}
[HttpPost]
[Authorize(Role.Administrator)]
public ActionResult Delete(int id)
{
/// do stuff
}
}
public class Role
{
public const string Administrator = "Administrator";
}
然后在我看来,使用扩展方法我会使用 CanDeleteRecordRole,例如:
@if(Model.DisplayIfAuthorized(Model.CanDeleteRecordRole))
{
<th>Delete record</th>
}
// and for td columns
@if(Model.DisplayIfAuthorized(Model.CanDeleteRecordRole))
{
<td>My action link here for deletion</td>
}
【问题讨论】:
-
不要学究,但我认为我认为在这种情况下很容易提出一个有意义的论点,即控制器操作上的属性提供的保护不是与相同的业务规则的表达
@if标记中的语句。在这种情况下,它们适用于相同的角色,并且在您的代码中位于相同的附近(相同的 V/C),但它们实际上是不同的规则。条件Model.CanDeleteRecordRole可能适用于与管理员完全不同的角色(如果您需要这种方式)。标记条件更加细化是最好的表达方式。 -
我想我误读了你显示的控制器和视图的关系,但你仍然想保留你所拥有的。如果您只使用跳过呈现删除链接的部分,您仍然会有一个公开的控制器操作,可以从您预期的身份验证方案之外的客户端调用。这需要一些知识并且可能是恶意的,但以 DRY 原则的名义省略 ATTRIBUTE 可能不是这里的最佳选择。 HTH
-
谢谢大卫。是的,我不是在考虑放弃属性,而是在考虑如何结合授权要求。例如。如果突然删除成为管理员 + 另一个角色,我宁愿在一个地方更改它,而不是记住要在多个等中进行......
-
我没有尝试过这种技术,但我绝对感兴趣。当我有机会时,我会尝试一下。它可能与您要查找的内容接近:Don't do Role Based do Activity-based auth checking
-
@DavidTansey 感谢您的链接。我必须消化这篇文章,但可能值得研究。任何事情都可能比我现在想的要好。
标签: asp.net-mvc controller authorization