在解決了ASP.NET訪問共享文件夾的問題之后,我們遇到了一個新的問題。在找找看(http://zzk.cnblogs.com/)調度建立索引過程中,在共享文件夾中創建新文件夾時出現錯誤:
System.UnauthorizedAccessException: Access to the path '\\192.168.18.18\ZzkIndex\Job\JobOffer\' is denied.
之前我們明明通過測試代碼驗證了可以在共享文件夾中建立文件夾的,現在怎么不行呢?
唯一不同之處在於這個操作是在System.Threading.Tasks.Task中進行的,也就是異步的。
前一篇文章中訪問共享文件夾時,用戶身份是通過web.config中的設置模擬的:
<system.web>
<identity impersonate="true" userName="ZzkIndexer" password="zzk.cnblogs.com"/>
</system.web>
現在出現UnauthorizedAccess異常,很有可能是在Task中異步執行時,不是以ZzkIndexer這個用戶身份執行的。
於是,從這個地方下手,把要解決的問題變為:“如何在異步操作中也一直使用web.config中所設置的模擬用戶身份?”
在互聯網海洋中苦苦尋覓。。。終於找到了線索!它就是 —— <alwaysFlowImpersonationPolicy> 。
它的藏身之處是 C:\Windows\Microsoft.NET\Framework64\v4.0.30319\Aspnet.config
<?xml version="1.0" encoding="UTF-8" ?>
<configuration>
<runtime>
<legacyUnhandledExceptionPolicy enabled="false" />
<legacyImpersonationPolicy enabled="true"/>
<alwaysFlowImpersonationPolicy enabled="false"/>
<SymbolReadingPolicy enabled="1" />
<shadowCopyVerifyByTimestamp enabled="true"/>
</runtime>
<startup useLegacyV2RuntimeActivationPolicy="true" />
</configuration>
MSDN中對alwaysFlowImpersonationPolicy的介紹:
Specifies that the Windows identity always flows across asynchronous points, regardless of how impersonation was performed.
指定無論模擬是如何執行的,Windows 標識始終流經異步點。
與alwaysFlowImpersonationPolicy相對應的是legacyImpersonationPolicy,MSDN中的介紹:
Specifies that the Windows identity does not flow across asynchronous points, regardless of the flow settings for the execution context on the current thread.
指定無論當前線程上的執行上下文的流設置如何,Windows 標識都不流經異步點。
於是,問題的解決方法顯而易見,在Aspnet.config中將alwaysFlowImpersonationPolicy設為true,將legacyImpersonationPolicy設為false,完整設置如下:
<?xml version="1.0" encoding="UTF-8" ?>
<configuration>
<runtime>
<legacyUnhandledExceptionPolicy enabled="false" />
<legacyImpersonationPolicy enabled="false"/>
<alwaysFlowImpersonationPolicy enabled="true"/>
<SymbolReadingPolicy enabled="1" />
<shadowCopyVerifyByTimestamp enabled="true"/>
</runtime>
<startup useLegacyV2RuntimeActivationPolicy="true" />
</configuration>
經過實際檢驗,該方法確實有效,目前為止未發現任何副作用。
(注:修改Aspnet.config后,需要重啟當前Web站點才能生效)