技巧和诀窍:使用PrincipalPermissionAttribute在业务和数据层中添加授权规则

来源:互联网 发布:linux dns soa 编辑:程序博客网 时间:2024/05/16 08:23

【原文地址】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

=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

标签:ASP.NET, .NET, Security, Tips and Tricks
 
(思归译)
 


原创粉丝点击