diff --git a/Security/Principal/WindowsImpersonatedIdentity.cs b/Security/Principal/WindowsImpersonatedIdentity.cs
index 144950b8..fe1ba64a 100644
--- a/Security/Principal/WindowsImpersonatedIdentity.cs
+++ b/Security/Principal/WindowsImpersonatedIdentity.cs
@@ -1,99 +1,65 @@
-#if (NET20 || NET35 || NET40 || NET45)
-using System;
-using System.ComponentModel;
+#if NET20 || NET35 || NET40 || NET45
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.
+ /// 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.
///
///
///
/// // The following code impersonates an account to perform work
/// using (new WindowsImpersonatedIdentity("bob", "WORKDOMAIN", "bobs_secret_passw0rd")
/// {
- /// // Perform impersonated work in the body. Once the 'using' statement closes,
- /// // the impersonation ends.
+ /// // Perform impersonated work in the body. Once the 'using' statement closes,
+ /// // the impersonation ends.
/// }
///
///
- public class WindowsImpersonatedIdentity : IDisposable, IIdentity
+ public class WindowsImpersonatedIdentity : WindowsLoggedInIdentity
{
private readonly WindowsImpersonationContext impersonationContext;
- private WindowsIdentity identity;
- private readonly bool ownId = true;
///
- /// Starts the impersonation with the given credentials. Please note that the account that instantiates this class needs to have the 'Act as part of
- /// operating system' privilege set.
+ /// Starts the impersonation with the given 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 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 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 plaintext password for the user account specified by .
+ /// 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.
+ /// 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.
+ /// 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 WindowsImpersonatedIdentity(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 var hToken))
- {
- using (hToken)
- {
- identity = new WindowsIdentity(hToken.DangerousGetHandle());
- impersonationContext = identity.Impersonate();
- }
- }
- else
- throw new Win32Exception();
- }
+ LogonUserProvider provider = LogonUserProvider.LOGON32_PROVIDER_DEFAULT) : base(userName, domainName, password, logonType, provider) => impersonationContext = AuthenticatedIdentity.Impersonate();
///
- /// 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.
+ /// 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 WindowsImpersonatedIdentity(WindowsIdentity identityToImpersonate)
- {
- identity = identityToImpersonate;
- impersonationContext = identity.Impersonate();
- ownId = false;
- }
+ public WindowsImpersonatedIdentity(WindowsIdentity identityToImpersonate) : base(identityToImpersonate) => impersonationContext = AuthenticatedIdentity.Impersonate();
/// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
- public void Dispose()
+ public override void Dispose()
{
impersonationContext?.Undo();
- if (ownId) identity?.Dispose();
- identity = null;
+ base.Dispose();
}
-
- /// Gets the authenticated identity.
- public WindowsIdentity AuthenticatedIdentity => identity;
-
- /// Gets the type of authentication used.
- string IIdentity.AuthenticationType => identity?.AuthenticationType;
-
- /// Gets a value that indicates whether the user has been authenticated.
- bool IIdentity.IsAuthenticated => identity?.IsAuthenticated ?? false;
-
- /// Gets the name of the current user.
- string IIdentity.Name => identity?.Name;
}
}
#endif
\ No newline at end of file
diff --git a/Security/Principal/WindowsLoggedInIdentity.cs b/Security/Principal/WindowsLoggedInIdentity.cs
new file mode 100644
index 00000000..2e600e7b
--- /dev/null
+++ b/Security/Principal/WindowsLoggedInIdentity.cs
@@ -0,0 +1,87 @@
+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;
+ }
+ }
+}
\ No newline at end of file