• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    迪恩网络公众号

ASP.NET安全问题--ASP.NET安全架构

原作者: [db:作者] 来自: [db:来源] 收藏 邀请

在开发Web程序中,我们可以选择用自己的方法来实现安全的策略,或者可以购买第三方的安全代码和产品,不管怎么样,都是要很大的花费的,幸好在.NET Framework中已经内置了安全的解决方案。        ASP.NET .NET Framework 联合IISWeb应用程序安全提供了一个基础结构。它的一个很明显的优势在于我们不必再编写自己的安全架构,我们可以利用.NET安全架构的内置的特性,而且整个安全的架构是经过测试和时间的考验了的。

       .NET安全架构包含了很多的类,这些类用来处理身份验证,授权,基于角色的授权,假冒(Impersonation),代码访问安全,还包含了一个用于构建自定义解决方案的基本架构。

       下面就开始:
     
   ASP.NET实现安全的过程 
    ASP.NET 安全架构分为几个关键的安全过程:身份验证,授权,假冒,加密提供提供了必需的功能。具体看看一些解释:
       
身份验证--指明是谁再访问我们的站点
       
授权----谁可以对哪些资源操作和访问?访问站点的用户是否被授权使用他所请求的资源?
       
假冒----准备假冒什么角色?(注:假冒不是贬义词,不是我们常说的假冒商品的假冒,因为不同的用户角色有不同的权限,如果  我们当前的用户无法访问某一特定的资源,我们就可以让想访问特定资源的用户假冒,更确切的说是模仿有权限访问特定资源的用户,简言之:用户A想访问C资源,但是没有权限,但是用户B可以访问,所以AB商量,A就用B的身份访问。具体的以后讲解)
       
下面我们具体看看每个安全的过程:
       
1.身份验证
       
身份验证是揭示用户标识(注:标识的概念我们后面马上就讲的,简言之,用户的ID 名称)并判断标识真实性的过程。很好理解,举个例子(大家注意例子中的一些术语):我们要取参加一个会议,我们就会取登记提供我们的一些证件即标识(表明我们的身份),一旦标识被确认,我们就会得到会议通行证,我们就可以带着通行证参加会议。而且会议中的每个人都可以通过我们的通行证了解我们的一些信息,如我们的名字,公司。身份验证就是:一旦标识被确定,我们就会得到一个可以识别我们的令牌,所以,再一个特定的区域内,不管我们在哪里,我们的标识都可以被识别。
       
ASP.NET中,有4中身份验证的模式:
       Widows身份验证(Windows Authentication)
       Forms
身份验证(Form Authentication)
       Passpot
身份验证(Passport Authentication)
       
自定义身份验证

       对于每一种身份验证,用户都需要在登录的时候提供凭证,一旦标识被核实,用户就会获得一个身份验证令牌,在Forms验证中,整个令牌就是FormsAuthenticationTicket,整个令牌就放在 cookie中,每次请求资源的时候,令牌就会提供用户的标识信息。

       2.授权
       
我们接着拿之前的那个会议的例子来看,授权就是表明我们可以做什么。进入会议厅以后,发现有很多不同的会议,专家级的,普通级的,不同人参加不同级别的会议。而且有些人可以参观整个会议厅,但是有些人只能在展览厅参观。这就是权限的不同而导致的。
       
所以,授权就是:以我们的标识信息为参考,批准或者拒绝访问我们请求的资源。还有一点要注意的是:我们一般是常用的是基于角色的授权,就是把用户分为一组一组,然后给每组不同的角色。
    
   假冒
       
假冒是在其他用户标识的上下文中执行代码的过程。在默认情况下,所有的ASP.NET代码都是在Domain/ASPNET用户账户下执行的,要利用其他的标识执行代码,假冒其他的标识,我们应该利用.NET安全架构中的内置的假冒的功能。它允许我们指定执行代码的用户账户,比如不同于Domain/ASPNET的预定用户账户。我们既可以利用ASP.NET中身份验证功能来验证用户,也可以利用标准的Windows身份验证来验证用户。

      然后我们可以利用我们的凭证,或者利用执行代码的预定义用户账户来设置所假冒的账户。
       
假冒还允许我们在不使用ASP.NET提供的身份验证和授权功能的情况下提供身份验证和授权:我们可以利用用户账户和他们相关权限支持WindowsIIS管理身份验证和授权。
       
假冒通常用于提供访问控制,比如授权,一个应用程序可以访问它所假冒的的用户可以访问的任何资源。例如,默认情况下,Domain/ASPNET用户不能对文件系统进行读写操作的,所以这个用户账户也无法在Enterprise Services中执行事务处理。但是利用假冒,用户就可以通过假冒一个特定的Windows账户完成这些事情,因为这个特定的账户有这个权限。因此,我们就可以保证一些用户可以对文件系统进行读写操作,而其他的一些用户仅仅执行读的操作。

       好了,上面讲了很多,我们现在就来小结一下,看看如何把身份验证,授权,假冒一起用于Web程序中。
       
当用户首次访问Web站点时,他们是匿名用户,我们不知道他们的标识,除非对他们进行身份验证,否则我们以后还是不知道他们的标识。当用户请求非安全的资源时,他们可以自动的访问这个资源(这就是非安全资源的定义)
       
当用户请求安全的受保护的资源时,就要如下步骤:
       1.
请求被发送到 Web服务器,由于此时这个用户标识还有被确认,所以用户就被重定向到登录页面
       2.
用户提供凭证,身份验证就对凭证进行验证和审核
       3.
如果用户凭证合法,就可以访问资源,否则,就不能。

       当用户请求安全的资源,但是该资源有特定权限的用户才能访问,就会发生下面步骤:
       1.
请求被发送到 Web服务器,由于此时这个用户标识还有被确认,所以用户就被重定向到登录页面
       2.
用户提供凭证,身份验证就对凭证进行验证和审核
       3.
把用户的凭证或者角色与被允许的用户或者角色进行比较,如果用户在列表中,那么他们就被准许访问这个资源,否则,拒绝。
       
如果启用了假冒,那么在这两种情况下,假冒都会发生。默认情况下,假冒是禁止的,可以修改配置文件添加<identity>元素启用:
 <configuration><system.web>
   <identity impersonate="true" userName="Xiaoyang/User" password="xiaoyang"/>
  </system.web> </configuration>

       <identity>中,把impersonate特性设置为true,拿userName password设为要假冒的用户账户。 如果假冒被启用,那么被审核的就是假冒的用户标识的凭证,而不是提交的凭证。这两种凭证有可能相同,需要注意的是:假冒是利用Web服务器中已有的用户访问,如IUser用户。
 

ASP.NET安全架构--如何实现.NET安全

ASP.NET安全架构为实现Web应用程序的安全模式提供了对象模型。不管我们选择哪一种的身份验证模式,其中很多的要素是相同的。登录到应用程序的用户按照他们提供的凭证被授予PrincipalIdentity。其中Principal对象表示的是用户的当前的安全上下文,包括用户的标识和他们所属的角色。Identity对象表示的是当前用户。Principal对象是利用Identity对象(表示用户的标识)创建的,而且它添加一些额外的信息,比如角色或者自定义的数据。
       
简言之:Principal=Identity+角色+自定义数据 

 大家要注意一点:身份验证是发生在ASP.NET运行的特定的时期的,记住这一点,具体的以后会讲的。 

    表示安全的上下文
       Identity
对象表示的是通过身份验证的用户。Identity对象的类型取决于所使用的身份验证,如,Windows身份验证使用的是 WindowsIdentity对象,而Froms验证使用的是FormsIdentity对象。


       
大家开始接触Identity概念有点难受,其实说白了Identity就是一个用户的标识,标识是什么?就是标明用户是什么,用户名字是什么而已,只是我们这里说的比较专业一点点而已。
       
另外,Principal对象表示的是通过身份验证的用户的组或者角色的成员:也就当前用户安全上下文。说安全上下文,说白点就是这个对象包含很多的用户身份的一些信息。Principal对象是有IIS中的Windows 身份验证自动的创建的,但是我们也可以创建普通的Principal对象(大家后面就慢慢明白的).
       
大家在编程的时候,或多或少用过HttpContent.Currrent.User属性,其实它表示的就是一个Principal对象.Principal对象是实现了IPrincipal接口的。
 
     
  IPrincipal 接口
       不同的身份验证模式对安全的上下文有不同的要求。我们可以利用Principal对象表示当前的安全上下文。IPrincipal接口定义了Principal对象的基本功能。而且我们还可以自定义安全的上下文对象,只要实现System.Security.Principal接口:

      
       
Identity属性--可以获取当前Principal对象的Identity.之前说过:Principal包含Identity就是这个原因。
       
IsInRole(string roleName)方法--可以判断当前的Principal对象是否属于指定的角色。大家在变成时候也用过类似的HttpContent.Current.User.Identity.IsInRole("Admin")语句。
 
       Principal
对象可以通过HttpContent.Current.User属性访问到,下面的代码大家应该都用过的:

 if(HttpContext.Current.User.Identity.IsAuthenticated) {

  lblUserName.Text=HttpContext.Current.User.Identity.Name+"已经登录";

 }
      
 (注:Identity是用户的标识,包含用户名。我们后面会讲的) 

      下面的代码就更加的常见了:判断当前的用户是否是管理员角色

 if(HttpContext.Current.User.IsInRole("Admin"){  // }

       接着我们就看看ASP.NET内置的实现了IPrincipal接口的对象:
 GenericPrincipal

       GenericPrincipal
类实现了IPrincipal接口。从名字可以看出GenericPrincipal对象表示的是一个一般的,基础的安全上下文,它仅仅只是定义了当前用户的角色,也就是说这个对象只是部分的实现了IPrincipal接口。(以后我们就把实现IPrincipal接口的对象称为 主体)。对于一种身份验证模式来讲,如 Windows身份验证,它使用的就是WindowsPrincipal,因为WindowsPrincipal更加具体的实现了IPrincipal。而在Forms验证中,用的只是一般的GenericPrincipal。也就是说,我们可以按照我们的要求实现自定义的Principal对象。下面会讲到的。
       IPrincipal
接口的每一个实现都要重写Identity属性和IsInRole方法。GenericPrincipal类的IsInRole方法是通过把角色值和在字符串在中定义的角色进行比较,而WindowsPrincipal类的IsInRole方法则是把角色和被分配到Windows用户帐户角色进行比较。

       我们可以创建一个在当前请求的整个生命周期中都要使用的GenericPrincipal类的实例,并把它赋值给HttpContent.Current.User属性。
 GenericPrincipal
的构造函数有两个参数:用户的GenericIdentity(用户标识GenericIdentity实现了IIdentity接口),和一个表示用户角色的字符串数组。所以我们之前说:Principal=Identity+角色就是这原因。
       GenericPrincipal
对象一旦被创建,就可以赋值到HttpContent.Current.User属性,用来表示当前请求用户的安全的上下文。
 
       
下面就是创建的代码例子:
//创建一般的GenericPrincipal //我们说过:标识就是包含用户名的对象,如下 包含一个名为"xiaoyang"的标识
 GenericIdentity identity=new GenericIdentity("xiaoyang");
 
//创建GenericPrincipal

//roles表示的是一个角色的字符串数组如role=new string{"Admin","Customer"};
 GenericPrincipal principal=new GenericPrincipal(identity,roles);
 
//附加
 HttpContext.Current.User=principal;
     
  注意:上面的代码是要写在特定的地方,也就是生命周期的特定的时候的,我们后面讲述。
       
说了Principal,下面就说说用户标识到底是什么,之前多次提到的。
        
用户标识
    
 Identity对象用于标识当前用户的标识。标识只能提供少量的安全上下文信息,如用户名。Identity对象可以验证用户。
 
      IIdentity接口
       IPrincipal接口一样,表示用户标识的对象都要实现这个接口。IIdentity接口定义了Identity对象的基本额的结构,定义如下:
       
AuthenticationType(string类型的)属性--它可以获取所使用的身份验证的类型,如,如果使用的Forms验证,该属性返回"Forms"字符串,所以我们自定义的标识可以返回"CustomIdentity"字符串。
 
      IsAuthenticated(bool类型)属性--标识用户是否通过身份验证。我们可以常常用HttpContext.Current.User.Identity.IsAuthenticated来判断用户是否已经登录。
 Name(string
类型的)属性--获取用户的名字。相信对HttpContext.Current.User.Identity.Name不陌生。
       
下面我们就看看我们自己的实现了IIdentity接口的标识类。
using System;
using System.Security.Principal;
public class CustomIdentity : IIdentity
{
       
private  string name;
//构造函数只接收一个string参数,大家可以看看之前我们代码:GenericIdentity identity=new GenericIdentity("xiaoyang");
        public CustomIdentity(string name){  this.name = name; }
        private string authenticateType = "CustomerIdentity";
        
public CustomIdentity(string name,string authenticateType) {
                
this.name = name;
                
this

该文章已有0人参与评论

请发表评论

全部评论

专题导读
热门推荐
阅读排行榜

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap