2011-05-20 53 views
0

在ASP.NET/C#中啓動一項服務(用ASP.NET/C#編寫)我希望這些指導者能夠啓動某項服務。我對這個代碼是:在我的網站上使用正確的權限

ServiceController svcController = new ServiceController("InvidualFileConversion"); 

    if (svcController != null) 
    { 
     try 
     { 
      svcController.Stop(); 
      svcController.WaitForStatus(ServiceControllerStatus.Stopped, TimeSpan.FromSeconds(10)); 
      svcController.Start(); 
     } 
     catch (Exception ex) 
     { 
      // error 
     } 
    } 

現在,當我運行此我得到錯誤「的計算機上無法打開InvidualFileConversion服務」,用另外的消息:「艾策斯被拒絕」。

我知道這是一個權限問題,但是我該如何給自己適當的權限? 不要拿出答案寫在我應該寫的地方:,因爲我已經試過了,並沒有奏效。另外我認爲,當我僅僅需要這幾行代碼時,這並不是真正爲整個網站設置的最佳方式。

編輯:我已經在我的代碼中添加了它,它仍然無效,我在同一個地方得到相同的異常。現在,它看起來像這樣:

protected void ConvertLink_OnClick(object sender, EventArgs e) 
{ 
    //convert(); 
    try 
    { 
     //--need to impersonate with the user having appropriate rights to start the service 
     Impersonate objImpersonate = new Impersonate(domainName, userName, userPassword); 
     if (objImpersonate.impersonateValidUser()) 
     { 
      //--write code to start/stop the window service 
      startWindowsService(); 
      objImpersonate.undoImpersonation(); 
     } 
    } 
    catch (Exception Ex) 
    { Response.Write(Ex.Message + Ex.InnerException.Message); } 
} 

private void startWindowsService() 
{ 
    ServiceController svcController = new ServiceController("InvidualFileConversion"); 

    if (svcController != null) 
    { 
     try 
     { 
      svcController.Stop(); 
      svcController.WaitForStatus(ServiceControllerStatus.Stopped, TimeSpan.FromSeconds(10)); 
      svcController.Start(); 
     } 
     catch (Exception ex) 
     { 
      // error 
     } 
    } 
} 

我有一個模擬類,看起來像這樣:

using System; 
using System.Data; 
using System.Configuration; 
using System.Linq; 
using System.Web; 
using System.Web.Security; 
using System.Web.UI; 
using System.Web.UI.HtmlControls; 
using System.Web.UI.WebControls; 
using System.Web.UI.WebControls.WebParts; 
using System.Xml.Linq; 
using System.Collections.Generic; 
using System.Security.Principal; 
using System.Runtime.InteropServices; 

/// <summary> 
/// Summary description for Impersonate 
/// </summary> 
public class Impersonate 
{ 

#region "Class Members" 
public const int LOGON32_LOGON_INTERACTIVE = 2; 
public const int LOGON32_PROVIDER_DEFAULT = 0; 
WindowsImpersonationContext impersonationContext; 
#endregion 

#region "Class Properties" 
public string domainName { get; set; } 
public string userName { get; set; } 
public string userPassword { get; set; } 
#endregion 

public Impersonate() 
{ 
    // 
    // TODO: Add constructor logic here 
    // 
} 
public Impersonate(string domainName, string userName, string userPassword) 
{ 
    this.domainName = domainName; 
    this.userName = userName; 
    this.userPassword = userPassword; 
} 

#region "Impersonation Code" 
[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 bool impersonateValidUser() 
{ 
    WindowsIdentity tempWindowsIdentity; 
    IntPtr token = IntPtr.Zero; 
    IntPtr tokenDuplicate = IntPtr.Zero; 

    if (RevertToSelf()) 
    { 
     if (LogonUserA(this.userName, this.domainName, this.userPassword, 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(); 
} 
#endregion 
} 

所以驗證事情的作品,但並沒有解決我的問題。我想現在還有問題與權限..我該怎麼做來改變這個?

編輯2:我把接下來的步驟包括這樣的:

  1. 創建其中標識設置爲用戶(這是一個管理員組的成員)一個應用程序池。
  2. 將服務「登錄」設置爲同一用戶。
  3. 再次運行Web應用程序後,它仍然失敗..

然而如果我把在管理員帳戶中的代碼證書,它的工作原理。(雖然我沒有使用管理員在應用程序池和服務...)

換句話說,我可以得到我想要的管理員帳戶,但不是我自己創建的帳戶,並具有管理員權限。我仍然希望與我自己創建的用戶一起工作,因爲我認爲將您的管理員憑據提供給用戶並不安全。

在我的工作服務器上,我有一個帳號,具有管理員權限但不是管理員帳號。

編輯3:這是越來越奇怪。我似乎現在工作但是: - 沒有模擬方法(它沒有工作)。 - 我只是做了羅布所說的。我有我自己的應用程序池與我定義的用戶。 windows服務也有該用戶指定的。 (用戶收到登錄服務權利) - 這樣,它似乎工作。 - 但如果通過我的網站進行調試,我仍然拒絕訪問。但是,如果只是通過瀏覽器和它的IP訪問我的網站,我可以啓動服務。

總結: - 模擬方法不起作用。 - 只要使用自行創建的應用程序池與currect用戶工作,如果服務有用戶也指定。但它在調試模式下不起作用(仍然存在Acces Denied)。

這篇文章是越來越大,我不知道是否仍然真的讀它..但也許還有人可以提供任何細節?恐怕它會在未來的某個地方再次失敗..

如有任何意見,將不勝感激! Floris

回答

2

您必須確保您的網站在有足夠啓動服務權限的用戶下運行。 確保在IIS 上禁用匿名身份驗證一種好的方法可能是創建一個有權在服務器Web上啓動服務的用戶,然後創建一個在該用戶下運行的應用程序池。然後,您必須讓您的Web網站使用該應用程序池。使用這種方法,所有網站都將在您剛剛創建的用戶下運行。 如果您希望更加細化,您仍然可以創建具有啓動服務權限的用戶,但不能將其用於應用程序池,而只能使用模擬啓動在該用戶下運行的服務的頁面。您只能對這種方法使用imporsonation功能!

更多的細節,你可以看看下面的鏈接:

http://forums.asp.net/t/1137962.aspx/1

http://support.microsoft.com/kb/306158

+0

Imporsonation似乎不工作還沒有。但是你在什麼層次創建用戶?它必須是服務器上的用戶嗎?還是通過IIS7? – 2011-05-20 12:00:47

+0

您這樣說: 1.創建一個有權在服務器Web上啓動服務的用戶。 **這是IIS還是服務器本身或..?** 2.創建一個在該用戶下運行的應用程序池。 **當您創建應用程序池時,您不指定任何用戶,那麼我該如何在該用戶下運行它?** 3.必須讓您的網站使用該應用程序池。 **這不是問題** 我試過的其他方法..但不工作.. – 2011-05-20 12:27:39

+0

這將在IIS本身,特別是在應用程序池。在IIS7上,它位於「應用程序池」>「高級設置」>「過程模型」>「標識」下。我們通常在Active Directory中創建一個擁有較高權限並且沒有密碼超時的特殊用戶,並將該用戶分配給應用程序池。 – Rob 2011-05-20 14:18:47