是否有一种开箱即用的简单方法来模拟 .NET 中的用户?
到目前为止,我一直在使用 this class from code project满足我所有的模拟要求。
是否有使用 .NET Framework 的更好方法?
我有一个用户凭证集(用户名、密码、域名),代表我需要模拟的身份。
最佳答案
.NET 空间中的“模拟”通常意味着在特定用户帐户下运行代码。与通过用户名和密码访问该用户帐户相比,这在某种程度上是一个独立的概念,尽管这两个想法经常结合在一起。
假冒
用于模拟的 API 在 .NET 中通过 System.Security.Principal
提供。命名空间:
较新的代码通常应使用
WindowsIdentity.RunImpersonated
,它接受用户帐户 token 的句柄,然后是Action
或Func<T>
用于执行代码。WindowsIdentity.RunImpersonated(userHandle, () => { // do whatever you want as this user. });
或
var result = WindowsIdentity.RunImpersonated(userHandle, () => { // do whatever you want as this user. return result; });
还有
WindowsIdentity.RunImpersonatedAsync
对于异步任务,在 .NET 5+ 或旧版本上可用,如果你拉入 System.Security.Principal.Windows Nuget 包。await WindowsIdentity.RunImpersonatedAsync(userHandle, async () => { // do whatever you want as this user. });
或
var result = await WindowsIdentity.RunImpersonated(userHandle, async () => { // do whatever you want as this user. return result; });
旧代码使用了
WindowsIdentity.Impersonate
检索WindowsImpersonationContext
的方法目的。该对象实现了IDisposable
, 所以通常应该从using
调用 block 。using (WindowsImpersonationContext context = WindowsIdentity.Impersonate(userHandle)) { // do whatever you want as this user. }
虽然此 API 仍然存在于 .NET Framework 中,但通常应避免使用。
访问用户帐户
在 Windows 中使用用户名和密码访问用户帐户的 API 是 LogonUser
- 这是一个 Win32 native API。目前没有用于调用它的内置托管 .NET API。
[DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
internal static extern bool LogonUser(String lpszUsername, String lpszDomain, String lpszPassword, int dwLogonType, int dwLogonProvider, out IntPtr phToken);
这是基本的调用定义,但是在生产中实际使用它还有很多需要考虑的地方:
- 获得具有“安全”访问模式的句柄。
- 适当关闭 native 句柄
- 代码访问安全 (CAS) 信任级别(仅限 .NET Framework)
- 路过
SecureString
当您可以通过用户按键安全地收集一个时。
与其自己编写代码,不如考虑使用我的 SimpleImpersonation库,它提供了一个围绕 LogonUser
的托管包装器获取用户句柄的 API:
using System.Security.Principal;
using Microsoft.Win32.SafeHandles;
using SimpleImpersonation;
var credentials = new UserCredentials(domain, username, password);
using SafeAccessTokenHandle userHandle = credentials.LogonUser(LogonType.Interactive); // or another LogonType
您现在可以使用 userHandle
使用上面第一部分中提到的任何方法。这是 SimpleImpersonation 库 4.0.0 版的首选 API。有关详细信息,请参阅项目自述文件。
远程计算机访问
重要的是要认识到模拟是一个本地机器的概念。不能使用只有远程机器知道的用户来模拟。如果要访问远程计算机上的资源,本地机器和远程机器必须附加到同一个域,或者两台机器的域之间需要有信任关系。如果任何一台计算机都是无域的,则不能使用 LogonUser
或 SimpleImpersonation 连接到该机器。
关于c# - 您如何在 .NET 中进行模拟?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/125341/