Set Identity of Thread

2019-01-15 12:21发布

In C#, how do I set the Identity of a Thread?

For example, if I have Thread MyThread, which is already started, can I change MyThread's Identity?

Or is this not possible?

3条回答
Root(大扎)
2楼-- · 2019-01-15 12:33

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.

GenericIdentity identity = new GenericIdentity("someuser", "Forms");
Thread.CurrentPrincipal = new GenericPrincipal(identity, new string[] { "somerole" });
查看更多
疯言疯语
3楼-- · 2019-01-15 12:43

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.IPrincipal that takes the type of Identity you are using.
For simplicity sake the .Net framework provides GenericPrincipal and GenericIdentity classes which can be used like this:

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

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.

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.

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.

查看更多
仙女界的扛把子
4楼-- · 2019-01-15 12:47

Yes, using impersonation literally

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);
        }
    }
}
查看更多
登录 后发表回答