在错误的域中模拟用户不会引发异常

时间:2010-06-07 19:18:46

标签: c# .net identity impersonation

我使用了常见的模拟代码并且它运行得很好,直到我在域中插入随机'dggdgsdg' - 然而它仍然有效...

if (LogonUser(Username, Domain, Password, Logon32LogonInteractive, Logon32ProviderDefault, ref existingTokenHandle) &&
    DuplicateToken(existingTokenHandle, (int)SecurityImpersonationLevel.SecurityDelegation, ref duplicateTokenHandle))
    {
            Identity = new WindowsIdentity(duplicateTokenHandle);
            ImpersonationContext = Identity.Impersonate();
    }
    else
    {
            throw new Win32Exception(Marshal.GetLastWin32Error());
    } 

我在我的域名上使用了一些TestUser,但它确实有效。我然后切换域,随意废话'werwerhrg',它冒充我的域名上的TestUser!为什么?我希望抛出异常,为什么它在起作用呢?

private const int Logon32LogonInteractive = 2;
private const int Logon32ProviderDefault = 0;

public enum SecurityImpersonationLevel
        {
            SecurityAnonymous = 0,
            SecurityIdentification = 1,
            SecurityImpersonation = 2,
            SecurityDelegation = 3
        }
[DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
private static extern bool LogonUser(String lpszUsername, String lpszDomain, String lpszPassword, int dwLogonType, int dwLogonProvider, ref IntPtr phToken);

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

[DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern bool DuplicateToken(IntPtr existingTokenHandle, int securityImpersonationLevel, ref IntPtr duplicateTokenHandle);

1 个答案:

答案 0 :(得分:4)

我认为答案在于如何执行身份验证。 LogonUser将尝试将您登录到其执行的本地计算机上。如果此计算机位于域中,则将根据AD控制器检查您的密码并进行验证。

但是,如果您提供域名,则无法找到它将作为后备版本对其自己的本地用户群进行身份验证。在本地它将使用NTLM(当客户端和服务器是同一台机器时使用NTLM)。 NTLM验证密码哈希值和用户名,似乎不打扰域名(ref doc)。

如果您使用UPN format instead and set domain to null,那么如果域名不存在,您将收到错误,并获得您想要的结果。

这类似于我在两台计算机上创建一个密码为B的用户A,然后这些用户可以使用本地权限访问彼此的计算机,而无需登录。

所有这一切都是为什么你应该远离域名世界中的本地帐户(至少使用相同的用户名,作为前缀),以及为什么非域名计算机不能在网络。如果可以而不是NTLM,为什么要全部使用Kerberos。

相关问题