我正在ASP.NET MVC4中构建一个应用程序作为学习练习。我想了解一下 身份验证和授权。这看起来很好,基于角色的授权似乎可以将某些控制器/操作限制为属于给定角色的用户。
我正在努力的是如何将其应用于属于单个用户的数据。使用论坛作为一个简单示例,如何实现功能,用户只能编辑或删除他们创建的帖子,但可以查看/添加评论到其他用户的帖子。这是否必须在代码中完成,方法是在允许更新之前检查与当前用户更新的帖子相关联的用户,如果它们不匹配则返回未授权。
是否有更优雅的解决方案可以应用而不是将此类逻辑应用于多个控制器/操作?
那里有大量的信息我只是想缩小搜索范围。任何人都可以建议一个很好的教程/文章。我一直在寻找Forms身份验证和成员身份,但我也对使用Identity的内容感兴趣。我也在使用Entity Framework。
由于
答案 0 :(得分:1)
这是否必须在代码中完成,方法是在允许更新之前检查与当前用户更新的帖子相关联的用户,如果他们不匹配则返回未授权。
是的,这正是你所做的。虽然基于角色的授权是用户和角色之间简单关系的问题,但数据访问级别授权通常很复杂,并且涉及自定义业务规则。
当然,创建一个通常用作警卫的薄层管理器可能会有很大帮助,这样您就可以将所有代码保持在一起:
[HttpPost]
public ActionResult PostFoo( FooModel model )
{
// keep the access manager separate from the
// domain layer. operate on IDs.
if ( new UserAccessManager( this.User ).
CanOperateOnFoo( model.IdSomething, model.IdWhateverElse ) )
{
}
else
// return 403 or a meaningful message
}
或
[HttpPost]
public ActionResult PostFoo( FooModel model )
{
// switch to the domain layer
Foo foo = Mapper.Map( model );
// make the access manager part of the domain layer
if ( foo.CanBeOperatedBy( this.User ) )
{
}
else
// return 403 or a meaningful message
}
答案 1 :(得分:0)
这是否必须在代码中完成,方法是在允许更新之前检查与当前用户更新的帖子相关联的用户,如果他们不匹配则返回未授权。
不,您希望避免将授权逻辑硬编码到代码中。这样做会导致:
是否有更优雅的解决方案可以应用而不是将此类逻辑应用于多个控制器/操作?
是的,有。就像您不会硬编码身份验证或登录到您的应用程序一样,您希望外部授权。这称为外部化授权管理(EAM)。有几个框架可以帮助您实现从Java中的Spring Security到基于声明的.NET授权到基于XACML的解决方案。
您需要考虑两种基本授权模型:
根据您提供的示例规则:
用户只能编辑或删除他们创建的帖子,但可以查看/添加评论到其他用户的帖子。
RBAC是不够的。您将需要使用ABAC(和XACML)来实现用户与请求的数据之间的关系。 XACML,eXtensible Access Control Markup Language是一个为您提供的标准:
使用XACML策略语言,您可以将示例重写为:
然后,从您的代码中,您所要做的就是发送授权请求: Alice可以查看帖子#123吗?。授权引擎(也称为策略决策点或PDP)将确定谁拥有该帖子并将做出决定, Deny 或 Permit 。
使用外部化授权和XACML的一个主要好处是,您可以将相同的一致授权应用于任何层(表示层,业务层,ESB,API,数据库......)和任何技术(Java,.NET,Python) ...)。
其他好处包括:
有几种开源和供应商解决方案可以解决这个市场问题。看看Axiomatics(免责声明:我为Axiomatics工作)或SunXACML(开源)。
HTH, 大卫。