繁体   English   中英

设置线程标识

[英]Set Identity of Thread

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

例如,如果我的线程 MyThread 已经启动,我可以更改 MyThread 的标识吗?

或者这是不可能的?

您可以通过创建新的主体来设置线程的标识。 您可以使用任何继承自System.Security.Principal.IIdentity 的Identity,但您需要一个继承自System.Security.Principal.IPrincipal的类,该类采用您正在使用的身份类型。
为简单起见,.Net 框架提供了GenericPrincipalGenericIdentity类,可以像这样使用:

 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;
 }

但是,这不会授予您使用新身份的 Windows 权限。 但如果您正在开发网站并希望创建自己的用户管理,它会很有用。

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

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

已接受答案的更新 [仅适用于 .NET 框架 4.5 及更高版本]
.NET 4.5 ,属性IsAuthenticated没有设置访问器,因此您不能直接将其设置为接受的答案。
您可以使用以下代码来设置该属性。

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

是的,从字面上使用模拟

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);
        }
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM