1

私は巨大なイントラネットアプリケーションであるいくつかのasp.netページに取り組んでいます。イントラネットアプリケーションプールはIDとして実行されNetworkService(尋ねないでください)、IUSR –IIS7として匿名認証を使用します。

イントラネットのホームディレクトリが次のようになっているとしましょうD:\Intranet\-問題のasp.netページはD:\Intranet\TimeSheets\V2\

問題の私のテストスクリプトはD:\Intranet\TimeSheets\V2\Post.aspx、これらの行で何かを実行します(投稿されたHTMLを[base 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を返します(これはアプリケーションプールのIDであり、匿名アクセス用に設定したアカウントではありません)。

これが匿名アカウントのオーバーライドに関する問題であることを確認するために、匿名の特定のユーザーで使用しようとしたADアカウントとして実行するようにアプリケーションプールを設定しました-これは正常に機能し、ファイルはリモート共有に正常に書き込まれます-クレデンシャルは適切です。IISがそれらを適切に使用していないだけです。

私の質問はこれです、匿名ユーザーのために異なるWindowsクレデンシャルで実行されているいくつかのサブフォルダーを持つことは可能ですか?もしそうなら、それは効果がないように見えるので、匿名アカウントを変更する以外に他に何をする必要がありますか?

私の2番目の質問はこれです:アクセス許可を上げるためにIISに依存する代わりに、asp.netページ内からこれを行う方法はありますか?つまり、ページが実行されているものとは異なる資格情報でファイルを書き込みますか?このサブフォルダーを独自のアプリケーションプールに移動することを考えましたが、それは少し面倒なようで、可能な限りそれを避けたいと思います。

(テキストの壁でごめんなさい)

4

1 に答える 1

1

さて、IISで壁に頭をぶつけた後、私はあきらめてコードルートに行きました。具体的にはadvapi32.dll、それLogonUserA()は、そしてさらに重要なことに、WindowsImpersonationContextオブジェクトですDuplicateToken()RevertToSelf()

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 に答える