2012-04-24 78 views
1

我正在工作的幾個asp.net頁面駐留的是一個巨大的intranet應用程序,intranet應用程序池作爲身份運行NetworkService (不要問)&使用匿名身份驗證作爲IUSR - IIS7。IIS7 - 拒絕訪問使用System.IO.StreamWriter()ASP.net頁面寫入共享

假設內網主目錄是D:\Intranet\ - 有關asp.net頁面駐留在D:\Intranet\TimeSheets\V2\

在質疑我的測試腳本是D:\Intranet\TimeSheets\V2\Post.aspx並執行這些方針的東西(需要發佈HTML [爲基地64串]) - 轉換爲HTML然後試圖寫入到網絡共享:

Dim TimeSheetInBase64 As String = Request.Form("HtmlToSave") 
Dim HtmlToSave As String = "" 
Dim SavePath As String = "\\DifferentFileServer\Public\Random Department\Posted Invoices\" 

'#### Convert the HTML from base64 back into HTML 
Try 
    Dim decodedBytes As Byte() 
    decodedBytes = Convert.FromBase64String(TimeSheetInBase64) 
    HtmlToSave = Encoding.Default.GetString(decodedBytes) 

Catch e As Exception 
    echo("Error decoding HTML: " & e.Message) 
    Exit Select 
End Try 

Try 
    Dim objWriter As New System.IO.StreamWriter(SavePath & "text.htm", False) 
    objWriter.WriteLine(HtmlToSave) 
    objWriter.Close() 
    echo("OK") 

Catch ex As Exception 
    Dim wi As WindowsIdentity = System.Security.Principal.WindowsIdentity.GetCurrent() 
    Dim user As String = wi.Name 
    echo("Error Saving Invoice To Disk (" & wi.Name & "): " & ex.Message) 
End Try 

的objWriter拋出試圖將文件寫入到遠程共享時的誤差:

Error Saving Invoice To Disk (NT AUTHORITY\NETWORK SERVICE): Access to the path '\\DifferentFileServer\Public\Random Department\Posted Invoices\text.htm' is denied. 

顯然這是因爲所涉及的頁面在應用程序池的範圍內運行。

所以,我試圖改變V2文件夾上的匿名特定用戶以使用具有對有問題共享的寫入訪問權限的AD帳戶 - 但是,即使在保存配置更改後重新啓動IIS,頁面仍然會拒絕訪問嘗試寫入文件時出錯(和WindowsIdentity.GetCurrent()仍然返回NT AUTHORITY \ NETWORK SERVICE(這是應用程序池的標識,而不是我爲匿名訪問設置的帳戶)

只是爲了確認這一點重寫匿名帳戶的問題,我設置了應用程序池作爲我試圖使用匿名特定用戶的AD帳戶運行 - 這工作正常,文件成功寫入遠程共享 - 所以憑據很好,它只是IIS沒有使用它們正常。

我的問題是這樣的,是否有可能爲匿名用戶使用不同的Windows憑據運行一些子文件夾?如果是這樣,除了更改匿名帳戶之外,還需要做些什麼,因爲這似乎沒有效果?

我的第二個問題是:不是依靠IIS來提升權限,有沒有什麼辦法可以在asp.net頁面內執行此操作,即使用不同的憑據從該頁面運行的不同憑據編寫文件? 我想過把這個子文件夾移動到它自己的應用程序池中 - 但是這看起來有點亂,我想盡可能避免這樣做。

(對不起,文字的牆)

回答

1

好了,撞我的頭與IIS牆後,我放棄了,去的代碼路徑,具體而言,advapi32.dll和它的LogonUserA()DuplicateToken() & RevertToSelf(),更重要的所述WindowsImpersonationContext對象:

http://msdn.microsoft.com/en-us/library/system.security.principal.windowsimpersonationcontext.aspx

首先,聲明功能來切換模擬上&關:

Private Function impersonateValidUser(ByVal userName As String, _ 
ByVal domain As String, ByVal password As String) As Boolean 

    Dim tempWindowsIdentity As WindowsIdentity 
    Dim token As IntPtr = IntPtr.Zero 
    Dim tokenDuplicate As IntPtr = IntPtr.Zero 
    impersonateValidUser = False 

    If RevertToSelf() Then 
     If LogonUserA(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 Not impersonationContext Is Nothing Then 
        impersonateValidUser = True 
       End If 
      End If 
     End If 
    End If 
    If Not tokenDuplicate.Equals(IntPtr.Zero) Then 
     CloseHandle(tokenDuplicate) 
    End If 
    If Not token.Equals(IntPtr.Zero) Then 
     CloseHandle(token) 
    End If 
End Function 

Private Sub undoImpersonation() 
    impersonationContext.Undo() 
End Sub 

用法當時超級簡單:

If impersonateValidUser("username", "domain", "password") Then 
    '#### Write the file then 'close' the Impersonation 
    undoImpersonation() 
End If 

在有需要下面的命名空間:

System.Web 
System.Web.Security 
System.Security.Principal 
System.Runtime.InteropServices 

啓示(羞恥,我花了這麼長時間才找到這個):

http://support.microsoft.com/kb/306158

相關問題