网页调用服务程序
???????N長時間都沒有寫博客了,似乎將自己松懈了,還是工作忙了,還是其他繁瑣之事?前幾天做一個小的功能,就是在web頁面調用系統服務,或者調用自己的服務程序。一些心得和大家分享一下,網上的相關知識點也比較少,MSDN上有很多,但是英文較差的我又點吃力。
? 場景1:我在客戶端做了一個服務程序,當機器一啟動,程序就開始運行,假定為:Server.exe
場景2:客戶端人員需要通過web頁面能夠控制服務程序Server.exe的啟動、運行和停止。
原以為簡單的調用便可,如下:
try {
?ServiceController sc = new ServiceController("IIsWebVirtualDir");
????? if (sc.Status == ServiceControllerStatus.Running)
????????? sc.Stop();
????? else
????????? sc.Start();
}
但是在IIS下查看結果:
?
可是在VS中調試并沒用這種異常,可是為什么是這樣呢?我想應該是在IIS中查看,是因為IIS登錄用戶應該沒有權限去啟動或者運行服務程序,當VS調試時,此時的用戶應該是Administrator用戶,當然有足夠的權限去開啟服務或者停止服務。
????????? 在查看MSDN之后,得知在IIS中可以模擬管理員登錄,便可掉用系統服務了。(在ASP.NET應用程序中使用身份模擬(Impersonation)) 當然介紹了很多方法:
1、ASP.NET中的身份模擬
2、模擬IIS認證帳號
3、在某個ASP.NET應用程序中模擬指定的用戶帳號
4、在代碼中模擬IIS認證帳號
5、在代碼中模擬指定的用戶帳號
這些資料地址:http://www.microsoft.com/China/Community/program/originalarticles/TechDoc/impersonation.mspx
客戶端調用服務程序,必須是IIS用戶登錄,那此時的IIS用戶的權限是不夠的,必須在代碼中模擬指定的用戶帳號進行登錄具體的程序如下://這些定義的常量是登錄的模式,如沒有桌面的,安全模式等等
public const int LOGON32_LOGON_INTERACTIVE = 2;
public const int LOGON32_PROVIDER_DEFAULT = 0;
public const int LOGON32_LOGON_SERVICE = 5;
public const int LOGON32_LOGON_BATCH = 4;
WindowsImpersonationContext impersonationContext;
[DllImport("advapi32.dll", CharSet = CharSet.Auto)]
public static extern int LogonUser(String lpszUserName,
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? String lpszDomain,
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? String lpszPassword,
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? int dwLogonType,
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? int dwLogonProvider,
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ref IntPtr phToken);
[DllImport("advapi32.dll", CharSet = System.Runtime.InteropServices.CharSet.Auto, SetLastError = true)]
public extern static int DuplicateToken(IntPtr hToken,
int impersonationLevel,
ref IntPtr hNewToken);
private bool impersonateValidUser(String userName, String domain, String password)
{ WindowsIdentity tempWindowsIdentity;
IntPtr token = IntPtr.Zero;
IntPtr tokenDuplicate = IntPtr.Zero;
if (LogonUser(userName, domain, password, LOGON32_LOGON_BATCH,
LOGON32_PROVIDER_DEFAULT, ref token) != 0)
{
if (DuplicateToken(token, 2, ref tokenDuplicate) != 0)
{
? ? ? tempWindowsIdentity = new WindowsIdentity(tokenDuplicate);
? ? ? impersonationContext = tempWindowsIdentity.Impersonate();
?? ? ? if (impersonationContext != null)
? ? ? ?? ? return true;
? ? ?? else
? ? ? ? ? return false;
}
else
? ? ? ? ? return false;
}
else
{
int flag= GetLastError();
return false;
}
}
[DllImport("kernel32.dll")]
public static extern Int32 GetLastError();
private void undoImpersonation()
{
impersonationContext.Undo();
}
protected void ButtonSure_Click(object sender, EventArgs e)
{
string username = this.txtUserName.Text;
string pwd = this.txtPassword.Text;
if (pwd == "")
{
this.Label1.Text = "此服務要求,計算機系統管理員不能使用空密碼,需填寫密碼!";
}
else
{
if (impersonateValidUser(username, ".", pwd))
{
string path = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "..\\sbin");
try
{
? ? ? ? ? ? ? ?ServiceController sc = new ServiceController("SstAppService");
? ? ? ? ? ? ? ?if (sc.Status == ServiceControllerStatus.Running)
? ? ? ? ? ? ? ?sc.Stop();
? ? ? ? ? ? ? ?sc.WaitForStatus(ServiceControllerStatus.Stopped);
? ? ? ? ? ? ? ?sc.Start();//此時可以調用服務程序
? ? ? ? ? ? ? ?this.Panel1.Visible = false;
? ? ? ? ? ? ? ?Response.Redirect("WebBSoftWare.aspx");
}
catch (Exception ex)
{
? ? this.Label1.Text = ex.ToString();
}
// Insert your code that runs under the security context of a specific user here.
undoImpersonation();
}
else
?? ?{
? ? ?? this.Label1.Text = "管理員模擬登錄失敗,請確認系統管理員用戶名和密碼!";
? ? }
? }
}
轉載于:https://www.cnblogs.com/stonespawn/archive/2009/05/05/1450285.html
總結
- 上一篇: ASP.NET MVC Action F
- 下一篇: Web安全(下)---主动类安全产品技术