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.
Let's say the Intranet Home Dir is D:\\Intranet\\
- the asp.net pages in question reside in 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:
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:
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).
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.
My question is this, is it possible to have some sub folders running with different windows credentials for anonymous users? 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? 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:
http://msdn.microsoft.com/en-us/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):
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.