设置线程标识

在C#中,如何设置线程的标识?

例如,如果我已经启动了Thread MyThread,我可以更改MyThread的身份吗?

或者这不可能吗?

您可以通过创建新的Principal来设置线程的标识。 您可以使用从System.Security.Principal.IIdentityinheritance的任何标识,但是您需要一个inheritance自System.Security.Principal.IPrincipal的类,该类采用您正在使用的标识类型。
为简单起见,.Net框架提供了GenericPrincipal和GenericIdentity类,可以像这样使用:

using System.Security.Principal; // ... GenericIdentity identity = new GenericIdentity("M.Brown"); identity.IsAuthenticated = true; // ... System.Threading.Thread.CurrentPrincipal = new GenericPrincipal( identity, new string[] { "Role1", "Roll2" } ); //... if (!System.Threading.Thread.CurrentPrincipal.IsInRole("Roll1")) { Console.WriteLine("Permission denied"); return; } 

但是,这不会为您提供使用新标识的窗口权限。 但是,如果您正在开发一个网站并希望创建自己的用户管理,它会很有用。

如果您想伪装成与当前使用的帐户不同的Windows用户,则需要使用模拟。 有关如何执行此操作的示例,请参阅System.Security.Principal.WindowsIdentity.Impersonate()的帮助。 您运行的帐户可以模拟哪些帐户存在限制。

在某些情况下,.Net框架会为您进行模拟。 发生这种情况的一个示例是,如果您正在开发ASP.Net网站,并且已为正在运行的虚拟目录或站点启用了集成Windows身份validation。

是的,从字面上使用模仿

 using (new Impersonation()) { // your elevated code } 

和类如下,对于设置我使用城堡字典适配器,如果它看起来很奇怪。

 [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 settings = Settings.Instance.Whatever; var domain = settings.Domain; var username = settings.User; var password = settings.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); } } } 

这是已接受答案的更新[适用于.NET framework 4.5及更高版本]
.NET 4.5 ,属性IsAuthenticated没有set访问器,因此您无法将其直接设置为接受的答案。
您可以使用以下代码设置该属性。

 GenericIdentity identity = new GenericIdentity("someuser", "Forms"); Thread.CurrentPrincipal = new GenericPrincipal(identity, new string[] { "somerole" });