[ASP.NET] 在ASP.NET中於IIS上模擬不同的執行身份
因為最近在製作的一些功能,有需要模擬不同身份,進入到各個AD伺服器進行驗證與部份功能的執行
在程式開發期間功能都是很正常的,但是一將程式放到IIS上就發生了無法執行的問題
後來發現是因為IIS上,應用程式集區的執行身份為ApplicationPoolIdentity,所以會有權限上不足的地方
我試著將執行身份更改為LocalService或是LocalSystem,但是執行的結果一樣是無法讀取AD伺服器的資料
但是將執行身份更改為AD內的帳號就可以正常執行
所以問題應該就是出在IIS的執行身份的識別上
這樣一來,只要能在程式執行的時候,動態去更改執行時的識別身份就可以了
更改識別身份的程式碼,MSDN上已經有可以參考的內容了,可以參考下面的連結頁面
這邊,我把程式碼拉出來變成一個個別的類別物件,以方便未來的使用
1.建立Impersonate物件,程式碼如下
public class Impersonate
{
public const int LOGON32_LOGON_INTERACTIVE = 2;
public const int LOGON32_PROVIDER_DEFAULT = 0;
WindowsImpersonationContext impersonationContext;
[DllImport("advapi32.dll")]
public static extern int LogonUserA(String lpszUserName,
String lpszDomain,
String lpszPassword,
int dwLogonType,
int dwLogonProvider,
ref IntPtr phToken);
[DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
public static extern int 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);
public string UserName { get; set; }
public string Domain { get; set; }
public string Password { get; set; }
public Impersonate(string strUserName, string strDomain, string strPwd)
{
this.UserName = strUserName;
this.Domain = strDomain;
this.Password = strPwd;
}
public bool ImpersonateValidUser()
{
WindowsIdentity tempWindowsIdentity;
IntPtr token = IntPtr.Zero;
IntPtr tokenDuplicate = IntPtr.Zero;
if (RevertToSelf())
{
if (LogonUserA(this.UserName, this.Domain, this.Password, LOGON32_LOGON_INTERACTIVE,
LOGON32_PROVIDER_DEFAULT, ref token) != 0)
{
if (DuplicateToken(token, 2, ref tokenDuplicate) != 0)
{
tempWindowsIdentity = new WindowsIdentity(tokenDuplicate);
impersonationContext = tempWindowsIdentity.Impersonate();
if (impersonationContext != null)
{
CloseHandle(token);
CloseHandle(tokenDuplicate);
return true;
}
}
}
}
if (token != IntPtr.Zero)
CloseHandle(token);
if (tokenDuplicate != IntPtr.Zero)
CloseHandle(tokenDuplicate);
return false;
}
public void UndoImpersonation()
{
impersonationContext.Undo();
}
}
2.要使用的時候,只要呼叫objImpersonate.ImpersonateValidUser這個Method就可以了
Impersonate objImpersonate = new Impersonate(txtUserName.Text, txtServer.Text, txtPwd.Text);
bool blImpersonate = objImpersonate.ImpersonateValidUser();
if (blImpersonate)
{
// 在這裡放入以特殊身份執行的功能
}
整個使用的檔案如下面附件,內含取出AD帳號與群組的功能,有興趣的人可以下載回去看看嘍