摘要
 
缺省情况下,ASP.NET应用程序以本机的ASPNET帐号运行,该帐号属于普通用户组,权限受到一定的限制,以保障ASP.NET应用程序运行的安全。但是有时需要某个ASP.NET应用程序或者程序中的某段代码执行需要特定权限的操作,比如某个文件的存取,这时就需要给该程序或相应的某段代码赋予某个帐号的权限以执行该操作,这种方法称之为身份模拟(Impersonation)。本文介绍了在ASP.NET应用程序中使用身份模拟的几种方法,并比较了它们各自适用的范围。
在阅读本文之前,建议您先阅读文章:《ASP .NET 中的身份验证:.NET 安全性指导》 以便对ASP.NET的安全控制有一个总体的了解。

目录
 
  • ASP.NET中的身份模拟
  • 模拟IIS认证帐号
  • 在某个ASP.NET应用程序中模拟指定的用户帐号
  • 在代码中模拟IIS认证帐号
  • 在代码中模拟指定的用户帐号
  • 更多信息

ASP.NET中的身份模拟
 
ASP.NET 通过使用身份验证提供程序来实现身份验证,一般情况下,ASP.NET的身份验证提供程序包括表单身份验证、Windows身份验证和Passport身份验证3种。当通过身份验证后,ASP.NET会检查是否启用身份模拟。如果启用,ASP .NET 应用程序使用客户端标识以客户端的身份有选择地执行。否则,ASP.NET应用程序使用本机身份标识运行(一般使用本机的ASPNET帐号),具体流程如下图所示:

 
在ASP.NET应用程序中使用身份模拟一般用于资源访问控制,主要有如下几种方法:
  • 模拟IIS认证帐号
  • 在某个ASP.NET应用程序中模拟指定的用户帐号
  • 在代码中模拟IIS认证帐号
  • 在代码中模拟指定的用户帐号

模拟IIS认证帐号
 
这是最简单的一种方法,使用经过IIS认证的帐号执行应用程序。您需要在Web.config文件中添加标记,并将impersonate属性设置为true:
<IDENTITY impersonate="true" />
在这种情况下,用户身份的认证交给IIS来进行。当允许匿名登录时,IIS将一个匿名登录使用的标识(缺省情况下是IUSR_MACHINENAME)交给ASP.NET应用程序。当不允许匿名登录时,IIS将认证过的身份标识传递给ASP.NET应用程序。ASP.NET的具体访问权限由该账号的权限决定。

模拟指定的用户帐号
 
当ASP.NET应用程序需要以某个特定的用户帐号执行,可以在Web.config文件的标记中指定具体的用户帐号:
<IDENTITY impersonate="true" userName="accountname" password="password" />
这时该ASP.NET应用程序的所有页面的所有请求都将以指定的用户帐号权限执行。

在代码中模拟IIS认证帐号
 
在代码中使用身份模拟更加灵活,可以在指定的代码段中使用身份模拟,在该代码段之外恢复使用ASPNET本机帐号。该方法要求必须使用Windows的认证身份标识。下面的例子在代码中模拟IIS认证帐号:
Visual Basic .NET
Dim impersonationContext As System.Security.Principal.WindowsImpersonationContext
Dim currentWindowsIdentity As System.Security.Principal.WindowsIdentity
currentWindowsIdentity = CType(User.Identity, System.Security.Principal.WindowsIdentity)
impersonationContext = currentWindowsIdentity.Impersonate()
'Insert your code that runs under the security context of the authenticating user here.
impersonationContext.Undo()
Visual C# .NET
System.Security.Principal.WindowsImpersonationContext impersonationContext;
impersonationContext = ((System.Security.Principal.WindowsIdentity)User.Identity).Impersonate();
//Insert your code that runs under the security context of the authenticating user here.
impersonationContext.Undo();

在代码中模拟指定的用户帐号
 
下面的例子在代码中模拟指定的用户帐号:
Visual Basic .NET
<%@ Page Language="VB" %>
<%@ Import Namespace = "System.Web" %>
<%@ Import Namespace = "System.Web.Security" %>
<%@ Import Namespace = "System.Security.Principal" %>
<%@ Import Namespace = "System.Runtime.InteropServices" %> <SCRIPT runat="server">
Dim LOGON32_LOGON_INTERACTIVE As Integer  = 2
Dim LOGON32_PROVIDER_DEFAULT As Integer = 0 Dim impersonationContext As WindowsImpersonationContext Declare Auto Function LogonUser Lib "advapi32.dll" (ByVal lpszUsername As String, _
                           ByVal lpszDomain As String, _
                           ByVal lpszPassword As String, _
                           ByVal dwLogonType As Integer, _
                           ByVal dwLogonProvider As Integer, _
                           ByRef phToken As IntPtr) As Integer
Declare Auto Function DuplicateToken Lib "advapi32.dll"(ByVal ExistingTokenHandle As IntPtr, _
                           ImpersonationLevel As Integer, _
                           ByRef DuplicateTokenHandle As IntPtr) As Integer Public Sub Page_Load(s As Object, e As EventArgs)
   If impersonateValidUser("username", "domain", "password") Then
      'Insert your code that runs under the security context of a specific user here.
      undoImpersonation()
   Else
      'Your impersonation failed. Therefore, include a fail-safe mechanism here.
   End If
End Sub Private Function impersonateValidUser(userName As String, _
domain As String, password As String) As Boolean
   Dim tempWindowsIdentity As WindowsIdentity
   Dim token As IntPtr
   Dim tokenDuplicate As IntPtr    If LogonUser(userName, domain, password, LOGON32_LOGON_INTERACTIVE, _
                LOGON32_PROVIDER_DEFAULT, token) <> 0 Then
      If DuplicateToken(token, 2, tokenDuplicate) <> 0 Then
                tempWindowsIdentity = new WindowsIdentity(tokenDuplicate)
                impersonationContext = tempWindowsIdentity.Impersonate()
     
                If impersonationContext Is Nothing Then
                   impersonateValidUser = False
                Else
                impersonateValidUser = True
                End If
      Else
         impersonateValidUser = False
      End If
   Else
      impersonateValidUser = False
   End If
End Function Private Sub undoImpersonation()
   impersonationContext.Undo()
End Sub
</SCRIPT>
Visual C# .NET
<%@ Page Language="C#"%>
<%@ Import Namespace = "System.Web" %>
<%@ Import Namespace = "System.Web.Security" %>
<%@ Import Namespace = "System.Security.Principal" %>
<%@ Import Namespace = "System.Runtime.InteropServices" %> <SCRIPT runat="server">
public const int LOGON32_LOGON_INTERACTIVE = 2;
public const int LOGON32_PROVIDER_DEFAULT = 0; WindowsImpersonationContext impersonationContext; [DllImport("advapi32.dll", CharSet=CharSet.Auto)]
public static extern int LogonUser(String lpszUserName,
                                  String lpszDomain,
                                  String lpszPassword,
                                  int dwLogonType,
                                  int dwLogonProvider,
                                  ref IntPtr phToken);
[DllImport("advapi32.dll", CharSet=System.Runtime.InteropServices.CharSet.Auto, SetLastError=true)]
public extern static int DuplicateToken(IntPtr hToken,
                                  int impersonationLevel, 
                                  ref IntPtr hNewToken); public void Page_Load(Object s, EventArgs e)
{
   if(impersonateValidUser("username", "domain", "password"))
   {
      //Insert your code that runs under the security context of a specific user here.
      undoImpersonation();
   }
   else
   {
      //Your impersonation failed. Therefore, include a fail-safe mechanism here.
   }
} private bool impersonateValidUser(String userName, String domain, String password)
{
   WindowsIdentity tempWindowsIdentity;
   IntPtr token = IntPtr.Zero;
   IntPtr tokenDuplicate = IntPtr.Zero;    if(LogonUser(userName, domain, password, LOGON32_LOGON_INTERACTIVE,
   LOGON32_PROVIDER_DEFAULT, ref token) != 0)
   {
      if(DuplicateToken(token, 2, ref tokenDuplicate) != 0)
      {
         tempWindowsIdentity = new WindowsIdentity(tokenDuplicate);
         impersonationContext = tempWindowsIdentity.Impersonate();
         if (impersonationContext != null)
            return true;
         else
            return false;
      }
      else
         return false;
   }
   else
      return false;
}
private void undoImpersonation()
{
     impersonationContext.Undo();
}
</SCRIPT>
下面介绍ASP.NET应用程序中使用身份模拟的一个简单应用。例如有一个ASP.NET应用程序要检查服务器端某个文件是否存在,相应的程序代码为:
bool a = File.Exists("D:\\Share\\test.txt");
缺省情况下该ASP.NET应用程序以ASPNET帐号运行。为了安全起见,ASPNET这个帐号并没有服务器端D:\Share\这个目录的访问权限。在不使用身份模拟的情况下,由于ASP.NET应用程序不具有访问该目录的权限,无论文件是否存在,File.Exists的返回值将永远是false。为了解决这个问题,可以另建一个用户帐号:FileExist,并赋予该帐号D:\Share\目录的访问权限。然后在该应用程序的Web.config文件的标记中指定具体的用户帐号:
<IDENTITY impersonate="true" userName="FileExist" password="password" />
来执行该程序。

更多信息
 
请访问以下链接获取更多信息:
1. INFO: Implementing Impersonation in an ASP.NET Application
http://support.microsoft.com/default.aspx?scid=kb;en-us;Q306158&SD=MSKB
2. INFO: ASP.NET Security Overview
http://support.microsoft.com/default.aspx?scid=kb;en-us;Q306590
3. ASP.NET Web Application Security
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpguide/html/cpconaspnetwebapplicationsecurity.asp

在ASP.NET应用程序中使用身份模拟(Impersonation)的更多相关文章

  1. 如何在 ASP.NET 应用程序中实现模拟用户身份(在ASP.NET中以管理员身份运行网站)

    前言 在实际的项目开发中,我们可能会需要调用一些非托管程序,而有些非托管程序需要有更高的身份权限才能正确执行.本文介绍了如何让IIS承载的ASP.NET网站以特定的账户执行,比如Administrat ...

  2. 介绍 ASP.NET Identity - ASP.NET 应用程序的成员身份认证系统

    ASP.NET Identity 是构建 ASP.NET web 应用程序的一种新的身份认证系统.ASP.NET Identity 可以让您的应用程序拥有登录功能,并可以轻松地自定义登录用户的相关数据 ...

  3. ASP.NET MVC程序中动态修改form的Action值

    在练习ASP.NET MVC时,为了实现一个小功能,POST数据至服务器执行时,需要动态修改form的action值. 下面Insus.NET列举一个例子来演示它.让它简单,明白易了解. 你可以在控制 ...

  4. [转]关于ASP.NET(C#)程序中TEXTBOX下动态DIV跟随[AJAX应用]

    本文转自:http://blog.csdn.net/lolenboy/article/details/1665814 说明: 环境:ASPNET(c#),SQL2K 事例:TEXTBOX下跟随DIV, ...

  5. asp.net SimpleImpersonation使用身份模拟访问局域网共享目录

    mvc中默认账户的权限很低,缺省情况下,ASP.NET应用程序以本机的ASPNET帐号运行,该帐号属于普通用户组,权限受到一定的限制,以保障ASP.NET应用程序运行的安全.但是有时需要某个ASP.N ...

  6. 从零搭建一个IdentityServer——聊聊Asp.net core中的身份验证与授权

    OpenIDConnect是一个身份验证服务,而Oauth2.0是一个授权框架,在前面几篇文章里通过IdentityServer4实现了基于Oauth2.0的客户端证书(Client_Credenti ...

  7. 在ASP.NET MVC应用程序中实现Server.Transfer()类似的功能

    在ASP.NET MVC应用程序中,如果使用Server.Transfer()方法希望将请求转发到其它路径或者Http处理程序进行处理,都会引发“为xxx执行子请求时出错”的HttpException ...

  8. 【记录】ASP.NET MVC 4/5 Authentication 身份验证无效

    在 ASP.NET MVC 4/5 应用程序发布的时候,遇到一个问题,在本应用程序中进行身份验证是可以,但不能和其他"二级域名"共享,在其他应用程序身份验证,不能和本应用程序共享, ...

  9. ASP.NET 操作Excel中的DCOM配置方式

    具体配置方式如下: 1. 组件服务管理窗口 在运行栏中输入命令:dcomcnfg,打开组件服务管理窗口,在组件服务->计算机->我的电脑->DCom配置->找到Microsof ...

随机推荐

  1. jsp jstl标签库核心标签

    JSTL标签库介绍 JSTL标签库的使用时为了弥补html标签的不足,规范自定义标签的使用而诞生的.使用标签的目的就是不希望在jsp页面中出现java逻辑代码 全称:JSTL标签库分类 核心标签库使用 ...

  2. bzoj1053&&51nod1060

    题解: 其实就是求1-n之中拥有最多约数的数 一个数x的质因数分解为p1^e1*p2^e2*...*pn^en,则正因数的个数为(e1+1)(e2+1)...(en+1) 那么发现,正因数的个数和p没 ...

  3. 慕课网笔记之oracle开发利器-PL/SQL基础

    实例1--if语句 /* 慕课网Oracle数据库开发必备之PL/SQL_2-3 判断用户从键盘输入的数字 1.如何使用if语句 2.接收一个键盘的输入(字符串) */ set serveroutpu ...

  4. EhLib的行Checkbox

    方法1 http://www.cnblogs.com/jupt/p/4291902.html 在Indicator中添加动态Checkbox,无需绑定数据源,支持全选 - Ehlib学习(二)   先 ...

  5. ansible 列表变量、字典变量

    ansible的变量不仅可以是单个的值,也可以为列表. - hosts: localhost gather_facts: no vars: - list: [1,2,3] tasks: - name: ...

  6. 在junit中添加fail--有test失败即build Failed

    项目使用jenkins做持续集成,ant来构建,发现在跑junit单元测试的时候,如果有test case失败了,ci的状态是黄色的unstable,而不是红色的failed,看起来很不爽.个人觉得b ...

  7. Bitdefender Internet Security 2013 – 免费3个月

    Bitdefender Internet Security 2013 – 免费3个月大约1分钟参加调查,申请3个月免费,缺陷是…要经过人工审核活动地址: 点此进入申请方法,最好用谷歌翻译(俄文)

  8. PostgreSQL角色和权限理解

    1.继承的权限只是继承该组的表的权限,用户对应的管理员权限则不会被继承. 2.inherit权限是说本角色是否继承别人的权限,而不是本权限能否被别的角色继承.   postgres=# create ...

  9. HTTP Header之Content-Type

    HTTP Header之Content-Type   目录 1. HTTP Header 2. 文件请求和接口请求 3. 几种 Content-Type 3.1 application/x-www-f ...

  10. 基于VUE2.0的分页插件(很好用,很简单)

    基于jQuery的分页插件很多,今天分享一下基于Vue的分页插件pagination.js,该插件使用用感觉很不错,简单不复杂,现将个人使用过程中的方法与遇到的问题以及实例分享出来. 下载解压的主要目 ...