1

ASP.NET サイトからネットワーク ドライブ上のファイルを読み取るために、ドメイン ユーザー アカウントを一時的に偽装したいと考えています。

サイト全体に偽装を設定したり、サーバーにマップされたドライブを設定したりしたくありません。

4

2 に答える 2

4

私はMichiel van Otegem のコードを使用することになりました: WindowsImpersonationContext が簡単になり、IDisposable の実装が追加されました。ASP.NET での偽装に関する別の質問でこれを見つけました。

使用法:

using (WindowsImpersonationContextFacade impersonationContext
     = new WindowsImpersonationContextFacade(
                    Settings.Default.ImpersonationDomain, 
                    Settings.Default.ImpersonationUser,
                    Settings.Default.ImpersonationPass))
                {
                    transactions  = TransactionLoader.Load(filePath);
                }

コード:

using System;
using System.Runtime.InteropServices;
using System.Security.Principal;
using System.Security.Permissions;
using System.ComponentModel;

namespace MyNamespace
{
    public class WindowsImpersonationContextFacade : IDisposable
    {
        [DllImport("advapi32.dll", SetLastError = true)]
        public static extern bool LogonUser(String lpszUsername, String lpszDomain,
                                            String lpszPassword, int dwLogonType, int dwLogonProvider,
                                            ref IntPtr phToken);

        [DllImport("kernel32.dll", CharSet = CharSet.Auto)]
        public static extern bool CloseHandle(IntPtr handle);

        private const int LOGON32_PROVIDER_DEFAULT = 0;
        private const int LOGON32_LOGON_INTERACTIVE = 2;

        private string m_Domain;
        private string m_Password;
        private string m_Username;
        private IntPtr m_Token;

        private WindowsImpersonationContext m_Context = null;

        protected bool IsInContext
        {
            get { return m_Context != null; }
        }

        public WindowsImpersonationContextFacade(string domain, string username, string password)
        {
            m_Domain = domain;
            m_Username = username;
            m_Password = password;
            Enter();
        }

        [PermissionSetAttribute(SecurityAction.Demand, Name = "FullTrust")]
        private void Enter()
        {
            if (this.IsInContext) return;
            m_Token = IntPtr.Zero;
            bool logonSuccessfull = LogonUser(
                m_Username,
                m_Domain,
                m_Password,
                LOGON32_LOGON_INTERACTIVE,
                LOGON32_PROVIDER_DEFAULT,
                ref m_Token);
            if (logonSuccessfull == false)
            {
                int error = Marshal.GetLastWin32Error();
                throw new Win32Exception(error);
            }
            WindowsIdentity identity = new WindowsIdentity(m_Token);
            m_Context = identity.Impersonate();
        }

        [PermissionSetAttribute(SecurityAction.Demand, Name = "FullTrust")]
        private void Leave()
        {
            if (this.IsInContext == false) return;
            m_Context.Undo();

            if (m_Token != IntPtr.Zero) CloseHandle(m_Token);
            m_Context = null;
        }

        public void Dispose()
        {
            Leave();
        }
    }
}
于 2009-05-18T20:46:03.710 に答える
3

実際、プロセスは非常に簡単です。次のようなコードを使用できます。

using System.Security.Principal;
...
// Obtain the authenticated user's Identity
WindowsIdentity winId = (WindowsIdentity)HttpContext.Current.User.Identity;
WindowsImpersonationContext ctx = null;
try
{
  // Start impersonating
  ctx = winId.Impersonate();
  // Now impersonating
  // Access resources using the identity of the authenticated user
}
// Prevent exceptions from propagating
catch
{
}
finally
{
  // Revert impersonation
  if (ctx != null)
    ctx.Undo();
}
// Back to running under the default ASP.NET process identity

あなたのコードは「偽装中」セクションに入ります。KEY は finally ブロックです。これは非常に重要です。この仕組みの詳細については、このMSDN記事を参照してください。

于 2009-05-18T20:46:23.943 に答える