Reputation: 4629
I am writing an application allowing users to manage groups in Active Directory. I want to use the identity of the currently logged in user so that they do not have to log into the application. The application works without issue remotely but after deploying to the test server (Windows 2008R2 IIS6) it is attempting to use the IIS APPPOOL identity instead of mine.
Relevant web.config settings:
<authentication mode="Windows"></authentication>
<identity impersonate="true" />
Code to check identity:
Session("Username") = ActiveDirectory.GetUsername( _
WindowsIdentity.GetCurrent.User.Translate(GetType(NTAccount)).Value _
)
ActiveDirectory is a class of helper functions and doesn't contain any impersonation logic.
How can I get the identity of the user accessing the application and not the IIS APPPOOL user?
Upvotes: 0
Views: 6350
Reputation: 1128
I believe the application will run with the identity of the application pool. In order to run as a different identity you will need to impersonate a user. MSDN has an article about it. Here is a class I wrote based off the article that helped me accomplish something similar.
class Impersonator : IDisposable
{
[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);
[DllImport("kernel32.dll", CharSet = CharSet.Auto)]
private extern static bool CloseHandle(IntPtr handle);
WindowsIdentity newId;
WindowsImpersonationContext impersonatedUser;
private bool isDisposed;
public Impersonator(string user, string password, string domain)
{
SafeTokenHandle safeTokenHandle;
const int LOGON32_PROVIDER_DEFAULT = 0;
//This parameter causes LogonUser to create a primary token.
const int LOGON32_LOGON_INTERACTIVE = 2;
// Call LogonUser to obtain a handle to an access token.
bool returnValue = LogonUser(user, domain, password, LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT, out safeTokenHandle);
newId = new WindowsIdentity(safeTokenHandle.DangerousGetHandle());
impersonatedUser = newId.Impersonate();
}
public void Dispose()
{
this.Dispose(true);
GC.SuppressFinalize(this);
}
public void Dispose(bool disposing)
{
if (!this.isDisposed)
{
if (disposing)
{
if (impersonatedUser != null)
{
this.impersonatedUser.Dispose();
}
if (newId != null)
{
this.newId.Dispose();
}
}
}
this.isDisposed = true;
}
~Impersonator()
{
Dispose(false);
}
private 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);
}
}
}
Basically create a new instance of the class when you want to impersonate the user and dispose of the class when you are done.
I hope this helps!
Upvotes: 2
Reputation: 11480
I'm not sure if this is along the lines of what you are trying to do. But to retrieve a user you would use something like this:
WindowsIdentity user = WindowsIdentity.GetCurrent();
WindowsPrincipal role = new WindowsPrincipal(user);
With the above solution you can actually check the role as well, or define Identity.Name
to supply you the information.
Another solution:
Environment.UserName;
Environment.GetEnvironmentVariable("USERNAME");
Now I know the WindowsIdentity
will pull across a Domain but the others I'm not sure how they will handle Active Directory. So you might have to do something with a Domain Context.
// Define Context
PrincipalContext context = new PrincipalContext(ContextType.Domain);
// Find User
UserPrincipal user = UserPrincipal.Current;
// Check User
if (user != null)
{
string loginName = user.SamAccountName; // Whatever "Login Name Means"
}
Here are good resources as well:
MSDN Docs On Account Management
Not sure if that is exactly what you meant, but hope that helps.
Upvotes: 1