147 votes

Comment faites-vous l’emprunt d’identité dans .NET ?

Y a-t-il un simple hors de la boîte pour emprunter l’identité d’un utilisateur dans .NET ?

Jusqu’ici j’ai utilisé cette classe du projet de code pour tous mes besoins d’emprunt d’identité.

Y a-t-il une meilleure façon de le faire à l’aide de .NET Framework ?

J’ai un jeu d’informations d’identification de l’utilisateur (nom d’utilisateur, mot de passe, nom de domaine) qui représente l’identité j’ai besoin d’emprunter l’identité.

321voto

Matt Johnson Points 33433

Après le saut à travers plusieurs posts sur ce sujet, je suis arrivé finalement à une classe simple pour encapsuler l'ensemble de l'usurpation de l'identité de la logique. Il vous permet de faire un simple appel comme ceci:

using (new Impersonation(domain, username, password))
{
    // do whatever you want
}

Ajouter cette classe à votre projet, et vous allez loin:

using System;
using System.Runtime.ConstrainedExecution;
using System.Runtime.InteropServices;
using System.Security;
using System.Security.Permissions;
using System.Security.Principal;
using Microsoft.Win32.SafeHandles;

namespace MyApplication
{
    [PermissionSet(SecurityAction.Demand, Name = "FullTrust")]
    public class Impersonation : IDisposable
    {
        private readonly SafeTokenHandle _handle;
        private readonly WindowsImpersonationContext _context;

        const int LOGON32_LOGON_NEW_CREDENTIALS = 9;

        public Impersonation(string domain, string username, string password)
        {
            var ok = LogonUser(username, domain, password,
                           LOGON32_LOGON_NEW_CREDENTIALS, 0, out this._handle);
            if (!ok)
            {
                var errorCode = Marshal.GetLastWin32Error();
                throw new ApplicationException(string.Format("Could not impersonate the elevated user.  LogonUser returned error code {0}.", errorCode));
            }

            this._context = WindowsIdentity.Impersonate(this._handle.DangerousGetHandle());
        }

        public void Dispose()
        {
            this._context.Dispose();
            this._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);
            }
        }
    }
}

Notez que je suis en utilisant le type de connexion 9 (nouveau les informations d'identification). Dans mon cas, j'ai besoin de vous connecter via de sécurité de confiance à un serveur sql server avec une connexion différente, de sorte que ce qui fonctionne le mieux. Vous pouvez avoir besoin d'un positions type d'ouverture de session en fonction de vos objectifs. Jetez un oeil à ce site pour d'autres types de connexion.


Mise à JOUR

Basé sur la poursuite de la rétroaction positive, j'ai décidé de nettoyer légèrement vers le haut et l'héberger dans une bibliothèque pour faciliter la consommation. Source et docs sur GitHub, prêt à l'emploi sur NuGet. Profitez-en!

62voto

spoon16 Points 17694

Voici une bonne vue d'ensemble de l' .NET de l'emprunt d'identité concepts.

Fondamentalement, vous serez en tirant parti de ces classes qui sont hors de la boîte dans la .NET framework:

Le code peut souvent obtenir de longues bien et c'est pourquoi vous voyez beaucoup d'exemples comme celui de la référence que de tenter de simplifier le processus.

21voto

Esteban Araya Points 12496

C'est probablement ce que vous voulez:

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

Mais j'ai vraiment besoin de plus de détails pour vous aider. Vous pourriez faire de l'usurpation d'identité avec un fichier de config (si vous essayez de le faire sur un site web), ou par le biais de la méthode de décorateurs (attributs) dans le cas d'un service WCF, ou par le biais... vous voyez l'idée.

Aussi, si nous parlons d'usurper l'identité d'un client qui a appelé à un service particulier (ou application web), vous devez configurer correctement le client afin qu'il passe les tokens.

Enfin, si ce que vous voulez vraiment faire est de Délégation, vous devez également le programme d'installation AD correctement de sorte que les utilisateurs et les machines sont approuvé pour la délégation.

Edit:
Jetez un oeil ici pour voir comment faire pour emprunter l'identité d'un autre utilisateur, et pour plus de documentation.

5voto

Gulzar Nazim Points 35342

Je mets quelques liens ici. Si vous estimez que ce n’est pas approprié pour votre cas, n’hésitez pas à commenter.

Comment implémenter l’emprunt d’identité dans une application ASP.NET

Recommande également ce post de Keith Brown.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X