Scott Guthrie 博客中文版

Scott Guthrie's Blog on ASP.NET and .NET (英文原版地址:http://weblogs.asp.net/scottgu)
随笔 - 180, 评论 - 1018, 引用 - 442

导航

工具

标签

每月存档

广告



访客

 

【原文地址】Tip/Trick: Adding Authorization Rules to Business and Data Layers using PrincipalPermissionAttributes
【原文发表日期】 Wednesday, October 04, 2006 8:50 AM

今夏早些时候,我写了2篇在ASP.NET中使用Windows认证的教程:《在内网(Intranet) ASP.NET Web应用中启用Windows认证》《在ASP.NET 中使用Windows认证和SQL服务器实现基于角色的安全机制》。我也贴出了Scott Mitchell著的非常棒的《ASP.NET 2.0之安全,成员和角色》系列教程的连接,该教程讨论了如何在面向Internet的web应用中使用表单认证和ASP.NET中新的成员和角色API。

这些教程讨论的是如何在你的网站上实现认证(authentication),即识别来访的用户是谁的过程。它们也示范了如何在你的网站上实现基于角色的管理,允许你将单独的用户从逻辑上分组成为较高层次的角色或组别,譬如,“管理员(admins)”, “朋友(friends)”,“订阅者(subscribers)”等等。这些教程也示范了如何实现授权规则来准予或拒绝用户或角色访问一个网站内的单独页面或URL。(上面提到的角色教程也示范了如何根据来访的用户的权限来显示/隐藏导航菜单节点。)

给业务和数据层添加安全授权规则

当你在一个ASP.NET应用中认证一个用户之后,通过认证的用户的身份(identity)将在服务器端处理用户请求的整个过程中自动流动(flow)。这意味着,你不需要从一个方法到另一个方法,或从一个类到另一个类,手工传递用户的身份(identity)。这使得在你整个应用中实现安全授权规则极其容易。

.NET中一个少为人知的特性是,在生成一个类的实例对象,或者访问一个对象的方法或属性(property)之前,能够让CLR自动根据这个身份信息来给用户授权的能力。这使得给你的业务和数据层添加安全授权规则极其容易,不必写太多编码。

你要做的就是使用System.Security.Permission命名空间下的PrincipalPermissionAttribute,在适当的类或类的成员上标记这个属性即可。譬如:

using System;
using System.Security.Permissions;

[PrincipalPermission(SecurityAction.Demand, Authenticated = true)]
public class EmployeeManager
{
    [PrincipalPermission(SecurityAction.Demand, Role 
"Manager")]
    
public Employee LookupEmployee(int employeeID)
    {
       // todo
    }

    [PrincipalPermission(SecurityAction.Demand, Role 
"HR")]
    
public void AddEmployee(Employee e)
    {
       // todo
    }
}

在上面的例子中,我给EmployeeManager类添加了一个PrincipalPermission属性。这么做的效果是,我要求在处理一个用户的web请求时,在实例化这个类之前,这个用户必须先通过认证(即先登录),Authenticated=true这要求强迫系统这么做。然后,我在LookupEmployee和AddEmployee方法上另加了2个安全要求。对于 LookupEmployee 方法,我要求通过认证的用户要调用这个方法的话,必须属于“经理(Manager)”这个角色。对于 AddEmploye 方法,我要求通过认证的用户要调用这个方法来给系统添加一个新的雇员的话,必须属于“人事部(HR)”这个角色。

这样,假如我偶然地在UI层引人了安全漏洞,有一些编码路径允许一个不是经理或不属于人事部的雇员导致这些方法被调用,那么我的业务层会自动防范这样的事情发生,并且抛出一个安全异常来。

并不局囿于任何特定的认证模式。它可以与表单认证,Windows认证,Passport认证,或者你想发明的任何定制的认证模式一起合作使用。它也可以和我想用的任何角色机制一起使用,这样,如果你建立或接入你自己的ASP.NET角色提供器的话,它自动会工作的。

PrincipalPermissionAttribute类是在标准的CLR mscorlib 程序集中实现的,这个程序集是所有的 .NET项目编译时都需要引用的。所以它不是特定于ASP.NET的,它可以在任何应用类型下使用,包括Windows和控制台程序。这个事实,除了使它更加有用外,也使得单元测试使用它的业务/数据层库项目更加容易。

在页面和控件里使用PrincipalPermissionAttribute

PrincipalPermissionAttribute可用在一个应用的任何类上。所以,除了在你的业务和数据层使用该属性外,你也可以在ASP.NET页面或者用户控件里使用该属性。譬如,想限制你的“MyPage”页面只能被拥有Manager角色的用户访问的话,你可以在该页的后台编码( code-behind)添加一个 PrincipalPermission属性(下面以VB编码为例):

Imports System.Security.Permissions

<PrincipalPermission(SecurityAction.Demand, Authenticated:
=True, Role:="Manager")> _
Partial Class MyPage
    
Inherits System.Web.UI.Page

End Class

ASP.NET安全方面的更多信息

想进一步了解ASP.NET安全的话,我建议你看一下我的ASP.NET安全资源列单以及我的ASP.NET技巧和诀窍网页

现在外面有2本专门的有关ASP.NET 2.0安全的书:Stefan Schackow的《Professional ASP.NET 2.0 Security, Membership and Role Management》一书以及本星期才出版的Dominick Baier的新书《Developing More Secure Microsoft ASP.NET 2.0 Applications》,Dominick Baier还著有一个非常棒的博客: http://www.leastprivilege.com

希望本文对你有所帮助,

Scott

 
(思归译)

相关文章

打印 | 张贴于 2006-10-05 08:40:00 | Tag:ASP.NET  .NET  Tips and Tricks  Security

留言反馈

#re: 技巧和诀窍:使用PrincipalPermissionAttribute在业务和数据层中添加授权规则 编辑
test
2006-10-12 15:32:00 | [匿名用户:saucer]
#re: 技巧和诀窍:使用PrincipalPermissionAttribute在业务和数据层中添加授权规则 编辑
en
2006-10-09 00:16:00 | [匿名用户:影视制作,宣传片制作,影视广告制作]
#re: 技巧和诀窍:使用PrincipalPermissionAttribute在业务和数据层中添加授权规则 编辑
也不一定都是Add Update Remove什么的吧
准确的说应该是“需要进行安全控制的最小功能点”
条目确实会很多,但既然你要实现动态角色权限控制,这个几乎是必经之路
2006-10-07 23:19:00 | [匿名用户:sunmast]
#re: 技巧和诀窍:使用PrincipalPermissionAttribute在业务和数据层中添加授权规则 编辑
对moslem所提到的Task还不是很理解,就是说一般的应用情况下 Task就按照 Add Update Remove这样划分?

就是针对数据的操作方式来划分? 还是可以根据业务上来划分?

要是根据业务上的话,感觉需要维护的Task会很多,

希望moslem的文章能早点儿出来,我第一个帮顶,:P
2006-10-06 09:56:00 | [匿名用户:M]
#re: 技巧和诀窍:使用PrincipalPermissionAttribute在业务和数据层中添加授权规则 编辑
十分感谢 moslem和saucer


2006-10-06 08:39:00 | [匿名用户:M]
#re: 技巧和诀窍:使用PrincipalPermissionAttribute在业务和数据层中添加授权规则 编辑
我最近参考别人的代码,以 AOP 的方式,结合 CAS (Code Access Security)和 ASP.NET Membership,实现了一个完整的、灵活的 RBAC 安全机制

具体思路是:

1) 在类的方法上以 Attribute 定义此方式能的功能,如 AddItem, UpdateItem, RemoveItem (方法的功能是确定的,不象 Role 是可变的,所以在这里硬编码是没有问题的)

2) 利用 Reflection 读取类中的所有 Attribute

3)在运行时可以新建 Role ,然后与 Attribute 建立 Mapping ,这样就可以确定 Role 能执行 Attribute 所对应的那些方法

4) 在运行时可以新建 User,然后与 Role 建立 Mapping (这可以利用 ASP.NET Membership来实现)

这样三个实体(User, Role, Task),两种关系(User<-->Role, Role<-->Task),就实现了灵活的、完整的 RBAC 模型。

有时间我会把关键代码和详细实现方式写出来。
2006-10-05 22:48:00 | [匿名用户:moslem]
#re: 技巧和诀窍:使用PrincipalPermissionAttribute在业务和数据层中添加授权规则 编辑
路过
2006-10-05 17:29:00 | [匿名用户:firefox]
#re: 技巧和诀窍:使用PrincipalPermissionAttribute在业务和数据层中添加授权规则 编辑
如何才能管理好这些代码里的角色?现在是硬编码的,如Role = "Manager"

如果我以后要增加新的角色,或者修改某个方法的地角色,如何灵活有效的进行修改? 可以实现动更改吗?
2006-10-05 15:37:00 | [匿名用户:M]
对不起,目前本随笔不允许发表新评论.

Powered by: Joycode MVC Blogger System