[英]IIS7 - Access Denied using System.IO.StreamWriter() ASP.net page to write to share
I am working on a few asp.net pages that reside is a huge intranet application, the intranet application pool runs as the Identity NetworkService
(dont ask) & uses anonymous authentication as IUSR – IIS7. 我正在处理几个驻留在一个巨大的Intranet应用程序中的asp.net页面,该Intranet应用程序池以Identity NetworkService
(不要问)身份运行,并使用匿名身份验证作为IUSR – IIS7。
Let's say the Intranet Home Dir is D:\\Intranet\\
- the asp.net pages in question reside in D:\\Intranet\\TimeSheets\\V2\\
假设Intranet主目录是D:\\Intranet\\
-有问题的asp.net页位于D:\\Intranet\\TimeSheets\\V2\\
My test script in question is D:\\Intranet\\TimeSheets\\V2\\Post.aspx
and does something on these lines (Takes posted HTML [as a base 64 string]) - converts to HTML then attempts to write to a network share: 我有问题的测试脚本是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
The objWriter throws an error when attempting to write the file to a remote share: 尝试将文件写入远程共享时,objWriter引发错误:
Error Saving Invoice To Disk (NT AUTHORITY\NETWORK SERVICE): Access to the path '\\DifferentFileServer\Public\Random Department\Posted Invoices\text.htm' is denied.
Obviously this is because the pages in question are running under the scope of the application pool. 显然,这是因为有问题的页面在应用程序池的范围内运行。
So, i tried changing the anonymous specific user on the V2 folder to use an AD account that has write access to the share in question - however, even after saving the config change, restarting IIS the page still gets an access denied error when trying to write the file (and WindowsIdentity.GetCurrent() still returns NT AUTHORITY\\NETWORK SERVICE (wich is the identiy of the application pool and NOT the account i set for anonymous access). 因此,我尝试将V2文件夹上的匿名特定用户更改为使用对相关共享具有写访问权限的AD帐户-但是,即使在保存配置更改后,重新启动IIS时,该页面仍然会遇到拒绝访问错误写入文件(WindowsIdentity.GetCurrent()仍然返回NT AUTHORITY \\ NETWORK SERVICE(这是应用程序池的标识,而不是我为匿名访问设置的帐户)。
Just to confirm this is a problem with overriding the anonymous account i set the application pool to run with as the AD account i was trying to use on the anonymous specific user - this works fine and the file is written successfully to the remote share - so the credentials are good, it's just IIS not using them properly. 只是要确认这是覆盖匿名帐户的一个问题,我将应用程序池设置为要与我要在匿名特定用户上使用的AD帐户一起运行-可以正常工作,并且文件已成功写入远程共享-因此凭据很好,只是IIS没有正确使用它们。
My question is this, is it possible to have some sub folders running with different windows credentials for anonymous users? 我的问题是,匿名用户是否可以使用不同的Windows凭据运行某些子文件夹? If so, what else do i need to do apart from changing the anonymous account as that seems to have no effect? 如果是这样,除了更改匿名帐户似乎无效以外,我还需要做什么?
My Second question is this: instead of relying on IIS to elevate the permissions, is there any way to do this from within the asp.net page, ie write the file with different credentials from what the page is running as? 我的第二个问题是:不是依赖IIS来提升权限,有什么方法可以在asp.net页内执行此操作,即使用与该页运行时的凭据不同的凭据写入文件吗? I've thought about moving this sub folder into it's own application pool – but that seems a little messy and I would like to avoid doing that if at all possible. 我曾考虑过将这个子文件夹移到它自己的应用程序池中-但这似乎有些混乱,并且我想尽可能避免这样做。
(Sorry for the wall of text) (对不起,我不知道该怎么办)
Well, after banging my head against the wall with IIS, i gave up and went the code route, specifically, advapi32.dll
and it's LogonUserA()
, DuplicateToken()
& RevertToSelf()
and more importantly the WindowsImpersonationContext object: 好吧,在我用IIS撞墙之后,我放弃并走了代码路线,特别是advapi32.dll
及其LogonUserA()
, DuplicateToken()
和RevertToSelf()
,更重要的是WindowsImpersonationContext对象:
http://msdn.microsoft.com/en-us/library/system.security.principal.windowsimpersonationcontext.aspx http://msdn.microsoft.com/zh-CN/library/system.security.principal.windowsimpersonationcontext.aspx
First, declare functions to toggle impersonation on & off: 首先,声明函数以启用或禁用模拟功能:
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
The usage was then super easy: 用法非常简单:
If impersonateValidUser("username", "domain", "password") Then
'#### Write the file then 'close' the Impersonation
undoImpersonation()
End If
The following namespaces where required: 需要以下命名空间:
System.Web
System.Web.Security
System.Security.Principal
System.Runtime.InteropServices
Inspiration (Shame it took me so long to find this): 灵感(可惜我花了很长时间才找到它):
http://support.microsoft.com/kb/306158 http://support.microsoft.com/kb/306158
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.