C# 设置线程标识
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/258857/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Set Identity of Thread
提问by Duncan
In C#, how do I set the Identity of a Thread?
在 C# 中,如何设置线程的标识?
For example, if I have Thread MyThread, which is already started, can I change MyThread's Identity?
例如,如果我的线程 MyThread 已经启动,我可以更改 MyThread 的标识吗?
Or is this not possible?
或者这是不可能的?
采纳答案by Martin Brown
You can set the Identity of a thread by creating a new Principal. You can use any Identity that inherits from System.Security.Principal.IIdentity, but you need a class that inherits from System.Security.Principal.IPrincipalthat takes the type of Identity you are using.
For simplicity sake the .Net framework provides GenericPrincipaland GenericIdentityclasses which can be used like this:
您可以通过创建新的主体来设置线程的标识。您可以使用任何继承自System.Security.Principal.IIdentity 的Identity ,但您需要一个继承自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", "Role2" }
);
//...
if (!System.Threading.Thread.CurrentPrincipal.IsInRole("Role1"))
{
Console.WriteLine("Permission denied");
return;
}
This won't however give you windows rights to stuff using the new identity. But it can be useful if you are developing a web site and want to create your own user management.
但是,这不会授予您使用新身份的 Windows 权限。但如果您正在开发网站并希望创建自己的用户管理,它会很有用。
If you want to pretend to be a different Windows user than the account you are currently using then you need to use impersonation. An example of how to do this can be found in the Help for System.Security.Principal.WindowsIdentity.Impersonate(). There are limitations about which accounts the account you are running under can impersonate.
如果您想伪装成与当前使用的帐户不同的 Windows 用户,则需要使用模拟。有关如何执行此操作的示例,请参见System.Security.Principal.WindowsIdentity.Impersonate()的帮助。您运行的帐户可以模拟哪些帐户是有限制的。
In some cases the .Net framework does impersonation for you. One example of where this occurs is if you are developing a ASP.Net web site and you have Integrated Windows Authentication switched on for the virtual directory or site you are running in.
在某些情况下,.Net 框架会为您进行模拟。发生这种情况的一个示例是,如果您正在开发 ASP.Net 网站,并且您为正在运行的虚拟目录或站点打开了集成 Windows 身份验证。
回答by dove
Yes, using impersonationliterally
是的,从字面上使用模拟
using (new Impersonation())
{
// your elevated code
}
and the class is as follows, for settings I use castle dictionary adaptor if it looks strange.
类如下,对于设置,如果看起来很奇怪,我使用城堡字典适配器。
[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);
}
}
}
回答by Hakan F?st?k
Update for the accepted answer [apply ONLY on .NET framework 4.5 and above]
In .NET 4.5
the property IsAuthenticated
has no set accessor, so you can not set it directly as the accepted answer doing.
You can use the following code for setting that property.
更新已接受的答案 [仅适用于 .NET 框架 4.5 及更高版本]
在.NET 4.5
该属性IsAuthenticated
中没有设置访问器,因此您不能将其直接设置为已接受的答案。
您可以使用以下代码来设置该属性。
GenericIdentity identity = new GenericIdentity("someuser", "Forms");
Thread.CurrentPrincipal = new GenericPrincipal(identity, new string[] { "somerole" });