Установить идентичность темы

В C#, как мне установить идентичность потока?

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

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

3 ответа

Решение

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

Обновление для принятого ответа [применимо ТОЛЬКО к.NET Framework 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);
        }
    }
}
Другие вопросы по тегам