Frage

Gibt es eine einfache aus der Box Möglichkeit, einen Benutzer in .NET zu verkörpern?

Bisher habe ich diese Klasse von Code-Projekt für alle unter Verwendung von meine Identitätswechsel Anforderungen.

Gibt es einen besseren Weg, es zu tun, indem Sie .NET Framework verwenden?

Ich habe einen Benutzer Berechtigungsset, (Benutzername, Passwort, Domain-Namen), die die Identität I zum Imitieren brauchen darstellt.

War es hilfreich?

Lösung

Hier finden Sie einige gute Übersicht über .NET Identitätswechsel Konzepte.

Grundsätzlich werden Sie diese Klassen werden nutzen, die aus der Box in dem .NET-Framework sind:

Der Code kann erhalten oft langwierig, obwohl, und das ist, warum Sie viele Beispiele, wie die, die Sie Referenz zu sehen, die versuchen, den Prozess zu vereinfachen.

Andere Tipps

„Identitätswechsel“ in dem .NET-Raum bedeutet in der Regel Code unter einem bestimmten Benutzerkonto ausgeführt wird. Es ist ein etwas getrenntes Konzept als über einen Benutzername und Passwort Zugriff auf das Benutzerkonto bekommen, obwohl diese beiden Ideen zusammen häufig paaren. Ich werde beschreiben sie beide, und dann erklären, wie mein SimpleImpersonation Bibliothek, die sie intern verwendet.

Identitätswechsel

Die APIs für den Identitätswechsel sind in .NET über den System.Security.Principal Namespace bereitgestellt:

  • Neuere Code (.NET 4.6+, .NET-Core, etc.) sollten in der Regel verwenden WindowsIdentity.Impersonate Verfahren zur Herstellung eines WindowsImpersonationContext Objekt abzurufen. Dieses Objekt implementiert IDisposable, so sollte in der Regel aus einem using Block aufgerufen werden.

    using (WindowsImpersonationContext context = WindowsIdentity.Impersonate(tokenHandle))
    {
        // do whatever you want as this user.
    }
    

    Während diese API existieren noch in .NET Framework, es in der Regel vermieden werden sollte, und ist in .NET Core oder .NET Standard-nicht zur Verfügung.

Zugriff auf das Benutzerkonto

Die API einen Benutzernamen und ein Passwort für die Verwendung von Zugriff auf ein Benutzerkonto in Windows zu gewinnen ist LogonUser - das ist eine Win32 native API ist. Es ist nicht eine eingebaute in .NET-API für sie anrufen, so dass man zu P / Invoke zurückgreifen müssen.

[DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
internal static extern bool LogonUser(String lpszUsername, String lpszDomain, String lpszPassword, int dwLogonType, int dwLogonProvider, out IntPtr phToken);

Dies ist die grundlegende Anruf Definition, aber es viel mehr ist, um tatsächlich mit ihm in der Produktion zu berücksichtigen:

  • Beschaffung einen Griff mit dem „sicheren“ Zugriffsmuster.
  • die native schließen Griffe passend
  • Codezugriffssicherheit (CAS) Vertrauensebene (in .NET Framework nur)
  • Passing SecureString, wenn Sie einen sicher über Tastatureingaben der Benutzer sammeln können.

Die Menge an Code zu schreiben, um all dies zu veranschaulichen, ist jenseits dem, was in einer Antwort Stackoverflow sein sollte, IMHO.

Ein kombiniertes und einfacher Ansatz

Anstatt alle diese Texte selbst zu schreiben, sollten Sie meine SimpleImpersonation Bibliothek, die den Zugang Identitätswechsel und Benutzer kombiniert in einer einzigen API. Es funktioniert gut in modernen und älteren Codebasen, mit dem gleichen einfachen API:

var credentials = new UserCredentials(domain, username, password);
Impersonation.RunAsUser(credentials, logonType, () =>
{
    // do whatever you want as this user.
}); 

oder

var credentials = new UserCredentials(domain, username, password);
var result = Impersonation.RunAsUser(credentials, logonType, () =>
{
    // do whatever you want as this user.
    return something;
});

Beachten Sie, dass es auf die WindowsIdentity.RunImpersonated API sehr ähnlich ist, aber erfordert nicht Sie etwas über Token-Griffe kennen.

Dies ist die API ab Version 3.0.0. Siehe das Projekt Readme für weitere Details. Beachten Sie auch, dass eine frühere Version der Bibliothek verwendet, um eine API mit dem IDisposable Muster, ähnlich wie WindowsIdentity.Impersonate. Die neuere Version ist viel sicherer, und beide sind intern noch verwendet wird.

Dies ist wahrscheinlich das, was Sie wollen:

using System.Security.Principal;
using(WindowsIdentity.GetCurrent().Impersonate())
{
     //your code goes here
}

Aber ich brauche wirklich mehr Details um Ihnen zu helfen. Sie könnten mit einer Konfigurationsdatei tun Identitätswechsel (wenn Sie versuchen, diese auf einer Website zu tun hat), oder durch Verfahren Dekorateure (Attribute), wenn es ein WCF-Dienst oder durch ... Sie bekommen die Idee.

Auch wenn wir einen Kunden über Identitätswechsel, die einen bestimmten Dienst (oder Web-App) genannt sprechen, müssen Sie den Client korrekt konfigurieren, dass sie die entsprechenden Token geht.

Wenn schließlich, was Sie wirklich wollen Delegation ist, müssen Sie auch die Einrichtung AD richtig, so dass Benutzer und Maschinen für die Delegierung vertrauenswürdig eingestuft werden.

Bearbeiten
Werfen Sie einen Blick hier , um zu sehen, wie man Identitätswechsel einen anderen Benutzer, und für die weitere Dokumentation.

Hier ist mein vb.net Hafen von Matt Johnson Antwort. Ich habe eine Enumeration für die Anmeldetypen. LOGON32_LOGON_INTERACTIVE war der erste ENUM-Wert, der für SQL Server gearbeitet. Meine Verbindungszeichenfolge wurde nur vertraut. Kein Benutzername / Kennwort in der Verbindungszeichenfolge.

  <PermissionSet(SecurityAction.Demand, Name:="FullTrust")> _
  Public Class Impersonation
    Implements IDisposable

    Public Enum LogonTypes
      ''' <summary>
      ''' This logon type is intended for users who will be interactively using the computer, such as a user being logged on  
      ''' by a terminal server, remote shell, or similar process.
      ''' This logon type has the additional expense of caching logon information for disconnected operations; 
      ''' therefore, it is inappropriate for some client/server applications,
      ''' such as a mail server.
      ''' </summary>
      LOGON32_LOGON_INTERACTIVE = 2

      ''' <summary>
      ''' This logon type is intended for high performance servers to authenticate plaintext passwords.
      ''' The LogonUser function does not cache credentials for this logon type.
      ''' </summary>
      LOGON32_LOGON_NETWORK = 3

      ''' <summary>
      ''' This logon type is intended for batch servers, where processes may be executing on behalf of a user without 
      ''' their direct intervention. This type is also for higher performance servers that process many plaintext
      ''' authentication attempts at a time, such as mail or Web servers. 
      ''' The LogonUser function does not cache credentials for this logon type.
      ''' </summary>
      LOGON32_LOGON_BATCH = 4

      ''' <summary>
      ''' Indicates a service-type logon. The account provided must have the service privilege enabled. 
      ''' </summary>
      LOGON32_LOGON_SERVICE = 5

      ''' <summary>
      ''' This logon type is for GINA DLLs that log on users who will be interactively using the computer. 
      ''' This logon type can generate a unique audit record that shows when the workstation was unlocked. 
      ''' </summary>
      LOGON32_LOGON_UNLOCK = 7

      ''' <summary>
      ''' This logon type preserves the name and password in the authentication package, which allows the server to make 
      ''' connections to other network servers while impersonating the client. A server can accept plaintext credentials 
      ''' from a client, call LogonUser, verify that the user can access the system across the network, and still 
      ''' communicate with other servers.
      ''' NOTE: Windows NT:  This value is not supported. 
      ''' </summary>
      LOGON32_LOGON_NETWORK_CLEARTEXT = 8

      ''' <summary>
      ''' This logon type allows the caller to clone its current token and specify new credentials for outbound connections.
      ''' The new logon session has the same local identifier but uses different credentials for other network connections. 
      ''' NOTE: This logon type is supported only by the LOGON32_PROVIDER_WINNT50 logon provider.
      ''' NOTE: Windows NT:  This value is not supported. 
      ''' </summary>
      LOGON32_LOGON_NEW_CREDENTIALS = 9
    End Enum

    <DllImport("advapi32.dll", SetLastError:=True, CharSet:=CharSet.Unicode)> _
    Private Shared Function LogonUser(lpszUsername As [String], lpszDomain As [String], lpszPassword As [String], dwLogonType As Integer, dwLogonProvider As Integer, ByRef phToken As SafeTokenHandle) As Boolean
    End Function

    Public Sub New(Domain As String, UserName As String, Password As String, Optional LogonType As LogonTypes = LogonTypes.LOGON32_LOGON_INTERACTIVE)
      Dim ok = LogonUser(UserName, Domain, Password, LogonType, 0, _SafeTokenHandle)
      If Not ok Then
        Dim errorCode = Marshal.GetLastWin32Error()
        Throw New ApplicationException(String.Format("Could not impersonate the elevated user.  LogonUser returned error code {0}.", errorCode))
      End If

      WindowsImpersonationContext = WindowsIdentity.Impersonate(_SafeTokenHandle.DangerousGetHandle())
    End Sub

    Private ReadOnly _SafeTokenHandle As New SafeTokenHandle
    Private ReadOnly WindowsImpersonationContext As WindowsImpersonationContext

    Public Sub Dispose() Implements System.IDisposable.Dispose
      Me.WindowsImpersonationContext.Dispose()
      Me._SafeTokenHandle.Dispose()
    End Sub

    Public NotInheritable Class SafeTokenHandle
      Inherits SafeHandleZeroOrMinusOneIsInvalid

      <DllImport("kernel32.dll")> _
      <ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)> _
      <SuppressUnmanagedCodeSecurity()> _
      Private Shared Function CloseHandle(handle As IntPtr) As <MarshalAs(UnmanagedType.Bool)> Boolean
      End Function

      Public Sub New()
        MyBase.New(True)
      End Sub

      Protected Overrides Function ReleaseHandle() As Boolean
        Return CloseHandle(handle)
      End Function
    End Class

  End Class

Sie müssen sich mit einem Using Anweisung verwenden einige Code enthalten, um imitierte zu laufen.

Weiteres Detail aus meiner früheren Antwort Ich habe ein nuget Paket erstellt Nuget

-Code auf Github

Beispiel: Sie verwenden können:

           string login = "";
           string domain = "";
           string password = "";

           using (UserImpersonation user = new UserImpersonation(login, domain, password))
           {
               if (user.ImpersonateValidUser())
               {
                   File.WriteAllText("test.txt", "your text");
                   Console.WriteLine("File writed");
               }
               else
               {
                   Console.WriteLine("User not connected");
               }
           }

Vieuw den vollständigen Code:

using System;
using System.Runtime.InteropServices;
using System.Security.Principal;


/// <summary>
/// Object to change the user authticated
/// </summary>
public class UserImpersonation : IDisposable
{
    /// <summary>
    /// Logon method (check athetification) from advapi32.dll
    /// </summary>
    /// <param name="lpszUserName"></param>
    /// <param name="lpszDomain"></param>
    /// <param name="lpszPassword"></param>
    /// <param name="dwLogonType"></param>
    /// <param name="dwLogonProvider"></param>
    /// <param name="phToken"></param>
    /// <returns></returns>
    [DllImport("advapi32.dll")]
    private static extern bool LogonUser(String lpszUserName,
        String lpszDomain,
        String lpszPassword,
        int dwLogonType,
        int dwLogonProvider,
        ref IntPtr phToken);

    /// <summary>
    /// Close
    /// </summary>
    /// <param name="handle"></param>
    /// <returns></returns>
    [DllImport("kernel32.dll", CharSet = CharSet.Auto)]
    public static extern bool CloseHandle(IntPtr handle);

    private WindowsImpersonationContext _windowsImpersonationContext;
    private IntPtr _tokenHandle;
    private string _userName;
    private string _domain;
    private string _passWord;

    const int LOGON32_PROVIDER_DEFAULT = 0;
    const int LOGON32_LOGON_INTERACTIVE = 2;

    /// <summary>
    /// Initialize a UserImpersonation
    /// </summary>
    /// <param name="userName"></param>
    /// <param name="domain"></param>
    /// <param name="passWord"></param>
    public UserImpersonation(string userName, string domain, string passWord)
    {
        _userName = userName;
        _domain = domain;
        _passWord = passWord;
    }

    /// <summary>
    /// Valiate the user inforamtion
    /// </summary>
    /// <returns></returns>
    public bool ImpersonateValidUser()
    {
        bool returnValue = LogonUser(_userName, _domain, _passWord,
                LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT,
                ref _tokenHandle);

        if (false == returnValue)
        {
            return false;
        }

        WindowsIdentity newId = new WindowsIdentity(_tokenHandle);
        _windowsImpersonationContext = newId.Impersonate();
        return true;
    }

    #region IDisposable Members

    /// <summary>
    /// Dispose the UserImpersonation connection
    /// </summary>
    public void Dispose()
    {
        if (_windowsImpersonationContext != null)
            _windowsImpersonationContext.Undo();
        if (_tokenHandle != IntPtr.Zero)
            CloseHandle(_tokenHandle);
    }

    #endregion
}

Ich bin mir bewusst, dass ich ziemlich spät für die Partei bin, aber ich halte, dass die Bibliothek von Phillip Allan-Harding , es ist die beste für diesen Fall und ähnliche.

Sie brauchen nur ein kleines Stück Code wie diese:

private const string LOGIN = "mamy";
private const string DOMAIN = "mongo";
private const string PASSWORD = "HelloMongo2017";

private void DBConnection()
{
    using (Impersonator user = new Impersonator(LOGIN, DOMAIN, PASSWORD, LogonType.LOGON32_LOGON_NEW_CREDENTIALS, LogonProvider.LOGON32_PROVIDER_WINNT50))
    {
    }
}

Und fügen Sie seine Klasse:

. NET (C #) Identitätswechsel mit Netzwerkberechtigungen

Mein Beispiel kann verwendet werden, wenn Sie die imitierten-Anmeldung benötigen Netzwerk-Anmeldeinformationen haben, aber es mehr Optionen.

Sie können mit dieser Lösung. (Use NuGet-Paket) Der Quellcode ist verfügbar auf: Github: https://github.com/michelcedric/UserImpersonation

Weitere Einzelheiten https: //michelcedric.wordpress. com / 2015/09/03 / Usurpation-didentite-dun-user-c-Benutzer-Identitätswechsel /

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top