4

LogonUserwin32apiを使用しています。

token = LogonUser(...)
WindowsIdentity newId = new WindowsIdentity(token);            
WindowsImpersonationContext impersonatedUser = newId.Impersonate();

ただし、この後にWCFサービスを呼び出すと、偽装されたIDを使用できなくなります。これは、impersonatedUser.ImpersonationLevelがImpersonationと等しいためだと思います。

これが理由ですか?ImpersonationLevel.Identificationのレベルは必要ですか?そのようなレベルを取得する方法は?

4

2 に答える 2

8

これがWCFで機能するかどうかはわかりません。しかし、ファイル システムに対してファイルの読み取りと書き込みを行うためのなりすましのために、実稼働 Web アプリで使用しています。AdvApi32.LogonUser、AdvApi32.DuplicateToken、および Kernel32.CloseHandle の API を定義し、完了したら WindowsImpersonationContext を必ず閉じる必要があります。

    /// <summary>impersonates a user</summary>
    /// <param name="username">domain\name of the user account</param>
    /// <param name="password">the user's password</param>
    /// <returns>the new WindowsImpersonationContext</returns>
    public static WindowsImpersonationContext ImpersonateUser(String username, String password)
    {
        WindowsIdentity winId = WindowsIdentity.GetCurrent();
        if (winId != null)
        {
            if (string.Compare(winId.Name, username, true) == 0)
            {
                return null;
            }
        }

        //define the handles
        IntPtr existingTokenHandle = IntPtr.Zero;
        IntPtr duplicateTokenHandle = IntPtr.Zero;

        String domain;
        if (username.IndexOf("\\") > 0)
        {
            //split domain and name
            String[] splitUserName = username.Split('\\');
            domain = splitUserName[0];
            username = splitUserName[1];
        }
        else
        {
            domain = String.Empty;
        }

        try
        {
            //get a security token

            bool isOkay = AdvApi32.LogonUser(username, domain, password,
                (int) AdvApi32.LogonTypes.LOGON32_LOGON_INTERACTIVE,
                (int) AdvApi32.LogonTypes.LOGON32_PROVIDER_DEFAULT,
                ref existingTokenHandle);

            if (!isOkay)
            {
                int lastWin32Error = Marshal.GetLastWin32Error();
                int lastError = Kernel32.GetLastError();

                throw new Exception("LogonUser Failed: " + lastWin32Error + " - " + lastError);
            }

            // copy the token

            isOkay = AdvApi32.DuplicateToken(existingTokenHandle,
                (int) AdvApi32.SecurityImpersonationLevel.SecurityImpersonation,
                ref duplicateTokenHandle);

            if (!isOkay)
            {
                int lastWin32Error = Marshal.GetLastWin32Error();
                int lastError = Kernel32.GetLastError();
                Kernel32.CloseHandle(existingTokenHandle);
                throw new Exception("DuplicateToken Failed: " + lastWin32Error + " - " + lastError);
            }
            // create an identity from the token

            WindowsIdentity newId = new WindowsIdentity(duplicateTokenHandle);
            WindowsImpersonationContext impersonatedUser = newId.Impersonate();

            return impersonatedUser;
        }
        finally
        {
            //free all handles
            if (existingTokenHandle != IntPtr.Zero)
            {
                Kernel32.CloseHandle(existingTokenHandle);
            }
            if (duplicateTokenHandle != IntPtr.Zero)
            {
                Kernel32.CloseHandle(duplicateTokenHandle);
            }
        }
    }
于 2009-06-15T14:35:50.707 に答える
1

この後、偽装された ID を使用できなくなりました

なりすましは、ネットワーク上ではなく、同じボックスへのアクセスに対して有効である必要があります。

Consultutah のコードが示すように、DuplicateToken() を呼び出すだけで、ログオン トークンを偽装トークンに変換してから使用できるようになる場合があります。

これは、impersonatedUser.ImpersonationLevel が Impersonation と等しいためだと思います。

他のシステムに対して偽装ユーザーとして行動する必要がある場合は、「委任」と呼ばれるより高いレベルの偽装が必要です。これは基本的に、ユーザーのパスワードを取得することと同じであるため、他のユーザーに対して自分自身を表すことができます。

于 2009-07-29T01:34:35.617 に答える