设置线程的身份

发布于 2024-07-08 11:19:21 字数 101 浏览 9 评论 0原文

在C#中,如何设置线程的身份?

例如,如果我有线程MyThread,它已经启动,我可以更改MyThread的Identity吗?

或者这是不可能的?

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

妥活 2024-07-15 11:19:21

您可以通过创建新的主体来设置线程的身份。 您可以使用从 System.Security.Principal.IIdentity,但您需要一个继承自 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 身份验证。

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", "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.

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.

欲拥i 2024-07-15 11:19:21

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

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

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" });
花开雨落又逢春i 2024-07-15 11:19:21

是的,使用模拟字面意义

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

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);
        }
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文