2012-04-24 82 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

相关问题