'WindowsImpersonationContext & Impersonate() not found in ASP.Core
I had the following in a .NET Framework 4.0 assembly:
var newId = new WindowsIdentity(duplicateTokenHandle);
WindowsImpersonationContext newId = ImpersonatedIdentity.Impersonate();
I'm porting it to ASP.Core, but WindowsImpersonationContext
and WindowsIdentity.Impersonate()
aren't found.
I've tried adding the following:
Type | Version |
---|---|
System.Security.Claims |
4.3.0 |
System.Security.Principal |
4.3.0 |
System.Security.Principal.Windows |
4.3.0 |
How do I perform impersonation in ASP.Core?
Update
It looks like it's not supported in .NET Core or .NET Standard - is there a work-around or do I have to resign to targeting the framework?
Solution 1:[1]
Necromancing.
Like this:
using System.Security.Principal;
namespace regeditor
{
public class WindowsLogin : System.IDisposable
{
protected const int LOGON32_PROVIDER_DEFAULT = 0;
protected const int LOGON32_LOGON_INTERACTIVE = 2;
public WindowsIdentity Identity = null;
private System.IntPtr m_accessToken;
[System.Runtime.InteropServices.DllImport("advapi32.dll", SetLastError = true)]
private static extern bool LogonUser(string lpszUsername, string lpszDomain,
string lpszPassword, int dwLogonType, int dwLogonProvider, ref System.IntPtr phToken);
[System.Runtime.InteropServices.DllImport("kernel32.dll", CharSet = System.Runtime.InteropServices.CharSet.Auto)]
private extern static bool CloseHandle(System.IntPtr handle);
// AccessToken ==> this.Identity.AccessToken
//public Microsoft.Win32.SafeHandles.SafeAccessTokenHandle AT
//{
// get
// {
// var at = new Microsoft.Win32.SafeHandles.SafeAccessTokenHandle(this.m_accessToken);
// return at;
// }
//}
public WindowsLogin()
{
this.Identity = WindowsIdentity.GetCurrent();
}
public WindowsLogin(string username, string domain, string password)
{
Login(username, domain, password);
}
public void Login(string username, string domain, string password)
{
if (this.Identity != null)
{
this.Identity.Dispose();
this.Identity = null;
}
try
{
this.m_accessToken = new System.IntPtr(0);
Logout();
this.m_accessToken = System.IntPtr.Zero;
bool logonSuccessfull = LogonUser(
username,
domain,
password,
LOGON32_LOGON_INTERACTIVE,
LOGON32_PROVIDER_DEFAULT,
ref this.m_accessToken);
if (!logonSuccessfull)
{
int error = System.Runtime.InteropServices.Marshal.GetLastWin32Error();
throw new System.ComponentModel.Win32Exception(error);
}
Identity = new WindowsIdentity(this.m_accessToken);
}
catch
{
throw;
}
} // End Sub Login
public void Logout()
{
if (this.m_accessToken != System.IntPtr.Zero)
CloseHandle(m_accessToken);
this.m_accessToken = System.IntPtr.Zero;
if (this.Identity != null)
{
this.Identity.Dispose();
this.Identity = null;
}
} // End Sub Logout
void System.IDisposable.Dispose()
{
Logout();
} // End Sub Dispose
} // End Class WindowsLogin
} // End Namespace
Usage:
// WindowsIdentity user = (WindowsIdentity)context.User.Identity;
// using (WindowsIdentity user = WindowsIdentity.GetCurrent())
using (WindowsLogin wi = new WindowsLogin("Administrator", System.Environment.MachineName, "TOP_SECRET"))
{
#if NET461
using (user.Impersonate())
#else
WindowsIdentity.RunImpersonated(wi.Identity.AccessToken, () =>
#endif
{
WindowsIdentity useri = WindowsIdentity.GetCurrent();
System.Console.WriteLine(useri.Name);
}
#if !NET461
);
#endif
}*
Solution 2:[2]
As @Tratcher mentioned you can use the RunImpersonated
in .netstandard. The following code sniped is taken from here.
var user = (WindowsIdentity)context.User.Identity;
#if NET461
using (user.Impersonate())
#else
WindowsIdentity.RunImpersonated(user.AccessToken, () =>
#endif
{
// var useri = WindowsIdentity.GetCurrent();
}
#if !NET461
);
#endif
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | BanksySan |
Solution 2 | ryancdotnet |