gpt4 book ai didi

.net - .NET 模拟登录线程安全吗?

转载 作者:行者123 更新时间:2023-12-02 06:19:58 24 4
gpt4 key购买 nike

如果使用如下代码来冒充其他用户,

[DllImport("advapi32.dll", SetLastError = true)]

private static extern bool

LogonUser(string lpszUsername, string lpszDomain,
string lpszPassword, int dwLogonType,
int dwLogonProvider, ref IntPtr phToken);
var handle = IntPtr.Zero;

const int LOGON32_LOGON_NETWORK = 3;
const int LOGON32_PROVIDER_DEFAULT = 0;
const int SecurityImpersonation = 2;
LogonUser(username, domain,
password, LOGON32_LOGON_NETWORK,
LOGON32_PROVIDER_DEFAULT, ref handle))

在两个不同的并发线程上,它们会互相干扰吗?即,当前登录的用户是与线程关联还是与主机进程关联?

我正在使用登录句柄创建一个 WindowsImpersonationContext 对象,作为我命名为“Impersonator”的类型实例中的私有(private)状态字段(代码如下)。因此,由于此 WindowsImpersonationContext 对象是此类型实例中的本地私有(private)字段,并且每次我想要模拟某些凭据集时都会创建此类型的新实例,因此我可以假设此 WindowsImpersonationContext 就是用于在 block 内执行代码期间执行所有 ACL 验证,例如

   using (Impersonator.Impersonate(userId, domain, password))
{
// Code I want to execute using supplied credentials
}

让我担心的是MSDN页面WindowsImpersonationContext 上的声明上面写着:

Any public static (Shared in Visual Basic) members of this type are thread safe. Any instance members are not guaranteed to be thread safe.

模仿者类:

public class Impersonator: IDisposable
{
#region Declarations
private readonly string username;
private readonly string password;
private readonly string domain;

// This will hold the security context
// for reverting back to the client after
// impersonation operations are complete
private WindowsImpersonationContext impersonationContext;
#endregion Declarations

#region Constructors

public Impersonator(string UserName,
string Domain, string Password)
{
username = UserName;
domain = Domain;
password = Password;
}
#endregion Constructors

#region Public Methods
public static Impersonator Impersonate(
string userName, string domain, string password)
{
var imp = new Impersonator(userName, domain, password);
imp.Impersonate();
return imp;
}

public void Impersonate()
{
impersonationContext = Logon().Impersonate();
}

public void Undo() {
impersonationContext.Undo();
}
#endregion Public Methods

#region Private Methods
private WindowsIdentity Logon()
{
var handle = IntPtr.Zero;

const int LOGON32_LOGON_NETWORK = 3;
const int LOGON32_PROVIDER_DEFAULT = 0;
const int SecurityImpersonation = 2;

// Attempt to authenticate domain user account
try
{
if (!LogonUser(username, domain,
password, LOGON32_LOGON_NETWORK,
LOGON32_PROVIDER_DEFAULT, ref handle))
throw new LogonException(
"User logon failed. Error Number: " +
Marshal.GetLastWin32Error());

// ----------------------------------
var dupHandle = IntPtr.Zero;
if (!DuplicateToken(handle,
SecurityImpersonation,
ref dupHandle))
throw new LogonException(
"Logon failed attemting to duplicate handle");

// Logon Succeeded ! return new WindowsIdentity instance
return (new WindowsIdentity(handle));
}
// Close the open handle to the authenticated account
finally { CloseHandle(handle); }
}

#region external Win32 API functions
[DllImport("advapi32.dll", SetLastError = true)]
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 static extern bool CloseHandle(IntPtr handle);
// --------------------------------------------

[DllImport("advapi32.dll", CharSet = CharSet.Auto,
SetLastError = true)]
public static extern bool DuplicateToken(
IntPtr ExistingTokenHandle,
int SECURITY_IMPERSONATION_LEVEL,
ref IntPtr DuplicateTokenHandle);
// --------------------------------------------
#endregion external Win32 API functions
#endregion Private Methods

#region IDisposable
private bool disposed;

public void Dispose() { Dispose(true); }

public void Dispose(bool isDisposing)
{
if (disposed)
return;
if (isDisposing)
Undo();
// -----------------
disposed = true;
GC.SuppressFinalize(this);
}

~Impersonator() {
Dispose(false);
}

#endregion IDisposable
}

最佳答案

它与任何东西都没有关联。您拥有的句柄是登录句柄。一旦有了这个句柄,您就可以使用该句柄来模拟线程上的用户(通过调用 WindowsIdentity.Impersonate )或进程(通过 CreateProcess API function 或通过模拟线程,然后创建一个新的 Process 实例,同时冒充用户)。

无论哪种方式,请调用 LogonUser API function不执行任何模拟,它只是为您提供执行模拟所需的用户句柄(假设您有权限)。

关于.net - .NET 模拟登录线程安全吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3833656/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com