【问题标题】:Impersonate a Active Directory user in MVC application with Windows Authentication使用 Windows 身份验证在 MVC 应用程序中模拟 Active Directory 用户
【发布时间】:2014-04-19 20:17:24
【问题描述】:

我正在为 Intranet MVC 应用程序构建一个管理模块。此应用程序实现 Windows 身份验证(用户自动登录)。

目前我所有的用户体验都基于他们的 HttpContext.User.Identity 数据。

我需要做的是能够模拟用户,以便在他们遇到问题时复制他们的体验。

使用表单身份验证,这非常简单......

我尝试替换 HttpContext 中的 IPrincipal.User 对象,但这只有一个 getter 而不是一个 setter。

任何指针将不胜感激。

谢谢。

【问题讨论】:

  • 您有要模拟的用户密码吗?
  • 我已经回答了,假设他有,不知道如果他没有,你将如何被允许
  • :) 我希望哈哈。好答案。 advapi32.dll 很好用
  • 这是我正在使用的代码......我基本上不是试图获取用户上下文,而是基于用户的数据,其中一些数据来自 AD,一些来自数据库。我正在他们构建一个保存在会话中的数据对象。会话数据会话数据 = 新会话数据(); WindowsIdentity 身份 = new WindowsIdentity("user@email.org"); sessionData.UserData = uService.GetUserInfo(identity); if (Session["SessionData"] == null) { Session["SessionData"] = sessionData; }

标签: asp.net-mvc asp.net-mvc-4 iis windows-authentication impersonation


【解决方案1】:
 using (new Impersonation()){
  // now working in context of whatever user you want
 }

这就是类

 [PermissionSet(SecurityAction.Demand, Name = "FullTrust")]
    public class Impersonation : IDisposable
    {
    private readonly SafeTokenHandle _handle;
    private readonly WindowsImpersonationContext _context;

    //const int Logon32LogonNewCredentials = 9; 
    private const int Logon32LogonInteractive = 2;

    public Impersonation()
    {
        var domain = "your domain;
        var username = "the user";
        var password = "their password";
        var ok = LogonUser(username, domain, password, Logon32LogonInteractive, 0, out _handle);
        if (!ok)
        {
            var errorCode = Marshal.GetLastWin32Error();
            throw new ApplicationException(string.Format("Could not impersonate the elevated user.  LogonUser returned error code {0}.", errorCode));
        }
        _context = WindowsIdentity.Impersonate(_handle.DangerousGetHandle());
    }

    public void Dispose()
    {
        _context.Dispose();
        _handle.Dispose();
    }

    [DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
    private static extern bool LogonUser(String lpszUsername, String lpszDomain, String lpszPassword, int dwLogonType, int dwLogonProvider, out SafeTokenHandle phToken);

    public sealed class SafeTokenHandle : SafeHandleZeroOrMinusOneIsInvalid
    {
        private SafeTokenHandle()
            : base(true) { }

        [DllImport("kernel32.dll")]
        [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
        [SuppressUnmanagedCodeSecurity]
        [return: MarshalAs(UnmanagedType.Bool)]
        private static extern bool CloseHandle(IntPtr handle);

        protected override bool ReleaseHandle()
        {
            return CloseHandle(handle);
        }
    }
}

【讨论】:

  • 供以后参考,基本上这个方案和this SO answer一样,那里好像也有Github项目+NuGet可用。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-06-30
  • 2013-12-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多