using System; using System.ComponentModel; using System.Security.Principal; using static Vanara.PInvoke.AdvApi32; namespace Vanara.Security.Principal { /// /// Impersonation of a user. Allows to execute code under another user context. Please note that the account that instantiates this class /// needs to have the 'Act as part of operating system' privilege set. /// public class WindowsLoggedInIdentity : IDisposable, IIdentity { private readonly SafeHTOKEN hToken; private readonly bool ownId = true; /// /// Provides an identity to a logged into user given the supplied credentials. Please note that the account that instantiates this /// class needs to have the 'Act as part of operating system' privilege set. /// /// /// A string that specifies the name of the user. This is the name of the user account to log on to. If you use the user principal /// name (UPN) format, User@DNSDomainName, the parameter must be NULL. /// /// /// A string that specifies the name of the domain or server whose account database contains the account. /// If this parameter is NULL, the user name must be specified in UPN format. If this parameter is ".", the account is validated by /// using only the local account database. /// /// A string that specifies the plain-text password for the user account specified by . /// /// Type of the logon. This parameter can usually be left as the default. For more information, lookup more detail for the /// dwLogonType parameter of the Windows LogonUser function. /// /// /// The logon provider. This parameter can usually be left as the default. For more information, lookup more detail for the /// dwLogonProvider parameter of the Windows LogonUser function. /// public WindowsLoggedInIdentity(string userName, string domainName, string password, LogonUserType logonType = LogonUserType.LOGON32_LOGON_INTERACTIVE, LogonUserProvider provider = LogonUserProvider.LOGON32_PROVIDER_DEFAULT) { if (string.IsNullOrEmpty(userName)) throw new ArgumentNullException(nameof(userName)); if (string.IsNullOrEmpty(password)) throw new ArgumentNullException(nameof(password)); if (string.IsNullOrEmpty(domainName) && !userName.Contains("@")) throw new ArgumentNullException(nameof(domainName)); if (LogonUser(userName, domainName, password, logonType, provider, out hToken)) { using (hToken) { AuthenticatedIdentity = new WindowsIdentity(hToken.DangerousGetHandle()); } } else throw new Win32Exception(); } /// /// Starts the impersonation with the given . Please note that the account that instantiates this class /// needs to have the 'Act as part of operating system' privilege set. /// /// The identity to impersonate. public WindowsLoggedInIdentity(WindowsIdentity identityToImpersonate) { AuthenticatedIdentity = identityToImpersonate; ownId = false; } /// Gets the authenticated identity. public WindowsIdentity AuthenticatedIdentity { get; private set; } /// Gets the type of authentication used. string IIdentity.AuthenticationType => AuthenticatedIdentity?.AuthenticationType; /// Gets a value that indicates whether the user has been authenticated. bool IIdentity.IsAuthenticated => AuthenticatedIdentity?.IsAuthenticated ?? false; /// Gets the name of the current user. string IIdentity.Name => AuthenticatedIdentity?.Name; /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. public virtual void Dispose() { if (ownId) AuthenticatedIdentity?.Dispose(); hToken?.Dispose(); AuthenticatedIdentity = null; } } }