Подтвердить что ты не робот

Установить идентификатор потока

В С#, как установить идентификатор потока?

Например, если у меня есть Thread MyThread, который уже запущен, я могу изменить идентификатор MyThread?

Или это невозможно?

4b9b3361

Ответ 1

Вы можете установить Identity потока, создав нового Принципала. Вы можете использовать любую Идентификацию, которая наследуется от System.Security.Principal.IIdentity, но вам нужен класс, который наследуется от System.Security.Principal.IPrincipal, который использует тип Identity, который вы используете.
Для простоты .Net framework обеспечивает 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 с использованием нового удостоверения. Но это может быть полезно, если вы разрабатываете веб-сайт и хотите создать собственное управление пользователями.

Если вы хотите притвориться другим пользователем Windows, чем используемая вами учетная запись, вам нужно использовать олицетворение. Пример того, как это сделать, можно найти в справке System.Security.Principal.WindowsIdentity.Impersonate(). Есть ограничения, по которым учетные записи, на которых вы работаете, могут выдавать себя.

В некоторых случаях .Net framework делает олицетворение для вас. Например, если вы разрабатываете веб-сайт ASP.Net, и вы включили встроенную проверку подлинности Windows для виртуального каталога или сайта, на котором вы работаете.

Ответ 2

Да, используя impersonation буквально

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

Ответ 3

Это обновление для принятого ответа [применимо к .NET framework 4.5 и выше]
В .NET 4.5 свойство IsAuthenticated не имеет установленного доступа, поэтому вы не можете установить его непосредственно в соответствии с принятым ответом.
Вы можете использовать следующий код для установки этого свойства.

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