It sounds like you want HostingEnvironment.Impersonate
Example:
using (var imp = HostingEnvironment.Impersonate())
{
// code now executes in the context of the authenticated user,
// rather than the service account
}
That works fantastically, unfortunately the standard here is to not use app pools as password management is easier for them if its on each team to keep them up to date by putting it in the web.config
Well, that seems counter-intuitive, but I've run into worse policies in my day, so I'm hardly one to judge. ;)
As I mentioned in my comment, there are overloads of Impersonate that will allow you to impersonate an arbitrary account. In order to do this, you must obtain the windows identity token for that user, and this is non-trivial, and not, to my knowledge, something that you can do 100% in managed code. You'll have to use unmanaged code, and you'll have to know the username and password of the impersonated account within your application. This is far less secure than simply setting the account as the App Pool ID, if you ever want to argue the point with your network architect, BTW. Just some ammo for ya.
Anyway, here's some example code I adapted from the internets:
#region native imports.
public const int Logon_LogonTypeInteractive = 2;
public const int Logon_ProviderDefault = 0;
public const int Duplicate_ImpersonationLevelImpersonate = 2;
[DllImport("advapi32.dll")]
public static extern bool LogonUser(string lpszUserName, string lpszDomain, string lpszPassword,
int dwLogonType, int dwLogonProvider, ref IntPtr phToken);
[DllImport("advapi32.dll", CharSet=CharSet.Auto, SetLastError=true)]
public static extern bool DuplicateToken(IntPtr hToken, int impersonationLevel, ref IntPtr hNewToken);
[DllImport("advapi32.dll", CharSet=CharSet.Auto, SetLastError=true)]
public static extern bool RevertToSelf();
[DllImport("kernel32.dll", CharSet=CharSet.Auto)]
public static extern bool CloseHandle(IntPtr handle);
#endregion native imports.
#region elsewhere...
public IntPtr GetWindowsTokenForImpersonation(string username, string password, string domain)
{
IntPtr loginToken = IntPtr.Zero;
IntPtr workingToken = IntPtr.Zero;
bool success
if(!RevertToSelf())
{
return IntPtr.Zero;
// failed to eliminate any existing impersonations. This block may not be necessary depending on your code
}
if(!LogonUserA(username, domain, password, Logon_LogonTypeInteractive, Logon_ProviderDefault, ref loginToken))
{
return IntPtr.Zero;
// failed to log in the user
}
if(!DuplicateToken(loginToken, Duplicate_ImpersonationLevelImpersonate, ref workingToken)
{
if(loginToken != IntPtr.Zero)
{
CloseHandle(loginToken);
}
return IntPtr.Zero;
// failed to get a working impersonation token
}
CloseHandle(loginToken);
return workingToken; // NOTE: You must dispose this token manually using CloseHandle after impersonation is complete.
}
#endregion elsewhere
#region where you want to impersonate
var token = GetWindowsTokenForImpersonation(username, password, domain);
if(token != IntPtr.Zero)
{
using(var imp = HostingEnvironment.Impersonate(token))
{
// code here executes under impersonation
}
CloseHandle(token);
}
#endregion