0

我正在使用以下Microsoft 示例。每次 WindowsIdentity 实例调用 .Impersonate() 时,什么都没有发生。没有错误,没有模仿。
在调用前后,当前身份始终是 AppPool 身份。
我还尝试了在网上找到的另一个示例 Impersonator 类,并且发生了同样的事情。

我对这些示例所做的唯一修改是在 LogOnUser 调用中将 LOGON32_LOGON_INTERACTIVE 更改为 LOGON32_LOGON_NETWORK,因为使用 Interactive 总是返回 0 错误。

这是一个在 Win2k8 服务器上运行的 ASP.NET 4.0 应用程序,试图模拟 AD 中的用户。

编辑: 我最初没有提到这一点,但我修改了 Microsoft 示例并将其变成了一个类,以便我可以从我的 ASP.NET 应用程序中获得它。我也有impersonate=trueweb.config。

4

3 回答 3

1

我最终找到了一个助手类,几年前我做过类似的事情。助手实现 IDisposable,因此只需将文件访问代码包装在“使用”中,如下所示:-

using (Impersonate imp = new Impersonate())
{
    // Code in here will run under the identity specified in the helper
}

这是帮助程序类的代码(我删除了“使用”以节省一些空间)。您会注意到用户帐户在构造函数中是硬编码的:

internal class Impersonate : IDisposable
{
    private const int LOGON32_LOGON_INTERACTIVE = 2;
    private const int LOGON32_PROVIDER_DEFAULT = 0;

    private bool _disposed = false;
    private WindowsImpersonationContext _context = null;

    [DllImport("advapi32.dll")]
    private static extern int LogonUserA(String lpszUserName, String lpszDomain, String lpszPassword, int dwLogonType, int dwLogonProvider, ref IntPtr phToken);
    [DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
    private static extern int DuplicateToken(IntPtr hToken, int impersonationLevel, ref IntPtr hNewToken);

    [DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
    private static extern bool RevertToSelf();

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

    internal Impersonate()
    {
        WindowsIdentity tempWindowsIdentity;
        IntPtr token = IntPtr.Zero;
        IntPtr tokenDuplicate = IntPtr.Zero;

        string domain = "<whatever>";
        string username = "<whatever>";
        string password = "<whatever>";

        try
        {
            if (RevertToSelf())
            {
                if (LogonUserA(username, domain, password, LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT, ref token) != 0)
                {
                    if (DuplicateToken(token, 2, ref tokenDuplicate) != 0)
                    {
                        tempWindowsIdentity = new WindowsIdentity(tokenDuplicate);
                        _context = tempWindowsIdentity.Impersonate();
                    }
                }
            }
        }
        finally
        {
            if (token != IntPtr.Zero)
            {
                CloseHandle(token);
            }

            if (tokenDuplicate != IntPtr.Zero)
            {
                CloseHandle(tokenDuplicate);
            }
        }
    }

    public void Dispose()
    {
        Dispose(true);
        GC.SuppressFinalize(this);
    }

    private void Dispose(bool disposing)
    {
        if (!_disposed)
        {
            if (disposing)
            {
                // Dispose any managed resources here.
            }

            // Stop the impersonation.
            _context.Undo();

            _disposed = true;

        }
    }
}

试一试,让我知道你的进展如何......

安德鲁

于 2012-05-09T09:07:28.960 回答
0

您链接的示例适用于控制台应用程序。如果您有一个 ASP.Net Web 应用程序,您希望您的代码在访问者的安全上下文中执行,您可以在 IIS 身份验证设置中启用 ASP.Net 模拟(在 IIS 管理器 MMC 管理单元中)。

于 2012-05-08T14:10:47.030 回答
0

为用户组授予对 App_Data 文件夹的写入权限解决了该问题。不确定这与模仿有什么关系。

于 2012-05-10T17:37:08.183 回答