1

我正在处理一些驻留的 asp.net 页面是一个巨大的 Intranet 应用程序,Intranet 应用程序池作为身份运行NetworkService(不要问)并使用匿名身份验证作为 IUSR – IIS7。

假设 Intranet Home Dir 是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 页面中执行此操作,即使用与页面运行的不同凭据编写文件?我曾考虑将这个子文件夹移动到它自己的应用程序池中——但这似乎有点混乱,如果可能的话,我想避免这样做。

(对不起文字墙)

4

1 回答 1

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

于 2012-04-24T19:47:26.520 回答