Установить идентичность темы - PullRequest
23 голосов
/ 03 ноября 2008

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

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

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

Ответы [ 3 ]

29 голосов
/ 03 ноября 2008

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

4 голосов
/ 22 августа 2015

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

GenericIdentity identity = new GenericIdentity("someuser", "Forms");
Thread.CurrentPrincipal = new GenericPrincipal(identity, new string[] { "somerole" });
3 голосов
/ 03 ноября 2008

Да, используя олицетворение буквально

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