数据库

修改ASP.NET程序运行帐号

2011-04-09

    在个人所经历的几个ASP.NET项目中经常被权限问题困扰,大部分时间都是因为站点的运行帐号配置有问题。偶然发现这篇文章,感觉对ASP.NET中各种帐号的配置及使用讲解比较透彻,读来受益匪浅,所以翻译过来跟大家分享。这篇是本人第一次翻译,有不准确或者错误的地方,大家多指点。

背景知识

     所有应用程序在进程内运行。在IIS6.0中,ASP.NET Web程序运行在IIS工作进程(w3wp.exe)内。在默认情况下,该进程以Network Service帐号下运行。相似的,在IIS5.0(以及在IIS5.0隔离模式下运行的IIS6.0)中,ASP.NET Web程序运行在ASP.NET工作进程(aspnet_wp.exe)内。该进程在默认情况下以ASPNET帐号运行。 ASP.NET的架构允许用户修改此配置,以保证Web程序的安全运行。

 

应用程序域与ASP.NET

      应用程序域(Application Domain)是与进程对等的CLR(Application domains are the common language runtime equivalent to process boundaries.)。一个进程可以包含多个应用程序域。尽管多个应用程序域同在一个进程内,运行在一个应用程序域中的代码无法访问被另一个应用程序域中的代码所使用的内存空间。

      在IIS6.0中,IIS会为每个应用程序池(Application Pool)创建一个IIS工作进程。每个应用程序池内都包含零到多个Web程序。每个Web应用程序都运行在各自的应用程序域内。应用程序域与Web应用程序的映射的好处在于当一个应用程序池中的Web程序出现严重错误时,运行在其他应用程序池中的Web程序不会受影响。

IIS与ASP.NET Identity

     如前所述,在默认情况下,IIS工作进程和ASP.NET工作进程分别以Network Service和ASPNET身份运行。在Window Server 2003系统中,用户可以通过查看ASP.NET Web程序的应用程序池的属性中的Identity标签来查看该进程的运行帐号,如下图所示:

 

 

 

        在Window 2000和XP系统中,用户可以查看Web服务器的machine.config文件中的<processModel>元素的配置来确定进程运行帐号。该属性支持一下两个最常见的属性:

    • username

        该属性指定ASP.NET工作进程的运行账户。该账户可以是任何有效本机帐号或者域帐号。除此之外,用户还可以指定以下值:

  • System : 该值指定ASP.NET工作进程以Local System帐号运行。Locao System具有较高的权限(具有完全的管理权限),故指定该帐号时需谨慎。
  • Machine :该值指定ASP.NET工作进程以ASP.NET service帐号运行。该身份就是Window Server2003下的Network Service帐号,WindowsXP下的ASPNET帐号。
    • password

       该值指定前面所设置用户的密码。如果上面的UserName指定的是Machine,该值应设为autogenerate。

     当IIS工作进程或者ASP.NET工作进程启动一个Web程序,而且该Web程序禁用了impersonation,那么该Web程序使用IIS或ASPNET工作进程中设置的帐号运行。如果Web程序启动了Impersonation,则Web程序使用通过IIS验证的用户帐号或者在Web.config中配置的帐号。可以通过以下2种方式启用Impersonation:

    <identity impersonate="true"/> 

    该条件下,Web程序使用通过IIS验证的帐号运行。

    <identity impersonate="true" userName="someUserName" password="somePassword"/>

    该配置指定运行Web程序使用所配置帐号运行。

       如果在IIS中只启用了匿名访问,IIS传递给Web程序的帐号是匿名帐号,亦即<machine>\IUSER_<machine>,其中<machine>是运行IIS的服务器名称。如果IIS中只启用了Windows集成验证,那么IIS传递给Web程序的帐号则是通过验证的Windows帐号。如果同时启用了两者,IIS传递给Web程序的帐号则是通过IIS验证的帐号。IIS首先尝试以匿名方式访问Web程序或者资源。如果匿名方式无权限访问,则IIS尝试使用Windows验证。

 

WindowsIdentity.GetCurrent()与User.Identity.Name

     获取ASP.NET 程序的当前用户帐号可以使用以下下两个对象:

  • WindowsIdentity.GetCurrent()

该方法返回一个WindowsIdentity实例,亦即运行该线程的帐号。

  • User.Identity.Name

User.Identity对象代表从IIS传递到Web程序的用户帐号。若IIS允许用户匿名访问某页面,则User.Identity.Name属性值为空字符串,否则,将会返回通过IIS验证的用户帐号。

     假设一个Web程序,其在IIS的配置为启用Windows集成验证,Web程序所使用的应用程序池的Identity属性配置为Network Service。下表对比了在不同Impersonation/Anonymous acess配置情况下,当域用户BVS\JamesH访问该Web程序时,上述两个对象的输出情况:

 


 

 

结论

     在启用Impersonation的情况下,Web程序以IIS传递过来的帐号运行。如果禁用了Impersonation,Web程序则以IIS工作进程或ASPNET工作进程所配置的帐号运行。IIS工作进程所使用的帐号在由应用程序使用的应用程序池的Identity属性指定。ASP.NET工作进程所使用的帐号在服务器的machine.config文件中的<processModel>节配置。