在Asp.net开发的应用程序中,会有以windows集成认证的用户登录方式。会有这样的应用场景:
用户在本地上传一个Excel文件,其中包含了一些在本地编辑好的业务数据,需要上传到服务器更新到数据库中。作为服务端代码需要作很多的检查,以确保用户编辑的数据是有效的,这就需要较长时间的操作,不可能让用户在客户端(如IE)前一直等待返回。这就需要用委托的异步调用或多线程来处理上传文件后的操作。
因为新开辟的线程不同于主线程,它是以运行Asp.net的进程的user来启动的。(XP下的asp.net的进程是aspnet_wp.exe,对应的user是ASPNET,而在Windows server2003是w3wp.exe,对应的user是NETWORK SERVICE)
在新线程中免不了要访问数据库等需要身份验证的操作,以Asp.net的进程的user来验证显然是不正确的,这就需要把主线程的身份传到新线程中,在新线程中进行模拟。好在.Net Framework为我们提供了很简便的方法,下面看一下实例:














































这里提供了异步方法LongTimeHandleAsync。
在开始异步调用之前,先取得当前线程的user信息curIndentity.然后最关键的代码就是:
WindowsImpersonationContext impersonatedUser = WindowsIdentity.Impersonate(curIndentity.Token);
在这里,就开始了身份的模拟。这是WindowsIdentity的静态方法,它也提供有实例方法。将之前user的Token传入进行模拟。特别要注意,在代码结束前一定要恢复用户的标识,所以,比较好的做法是在try/catch/finally的finally块中调用impersonatedUser.Undo()
如果不进行身份模拟,string userName的值会是"ASPNET"(或"NETWORK SERVICE")而不是用户的Window user.