IIS應用程式集區自訂身份識別後如何讓 ASP.NET 正常執行

我們都知道 ASP.NET 在 IIS 6.0 中運行的時候,真正的執行權限使用者是應用程式集區(Application Pool)的身份識別(Identity)頁籤中定義的那位使用者,預設的使用者是「網路服務(NETWORK SERVICE)」,而且實際在執行的程序名稱(Process Name)為 w3wp.exe,各位可以從工作管理員中看到。

我們先設定一種情境,如果一台 IIS 中有兩個 ASP.NET 網站,分別由不同的開發團隊或客戶所管理,而兩個網站都有設定檔案上傳的功能,因此兩個網站一定會有特定目錄需要賦予 ASP.NET 可寫入權限,因為在 IIS 中 ASP.NET 的預設權限使用者就等於應用程式集區中定義的身份識別使用者,也就是所謂的 NETWORK SERVICE 系統使用者。

如果當其中第一個網站被入侵或值入後門程式時,也代表著這些後門程式正以 NETWORK SERVICE 的身份在你的主機中肆虐,攻擊的對象即便僅限於「網站」,但當然也包括第二個網站的部分可寫入路徑。

若要增強網站間的安全性與隔離性,我們這時就會需要修改應用程式集區(Application Pool)的身份識別設定,讓兩個 ASP.NET 網站個別使用不同的身份識別來執行所有的程式。

---

我想應該也有人試過修改 IIS 中應用程式集區(Application Pool)的身份識別:

  1. 先在系統中新增一位新的使用者 (假設叫做 User1 )
  2. 修改 IIS 中應用程式集的身份識別設定 (如下圖)

修改 IIS 中應用程式集區(Application Pool)的身份識別設定

但很不幸的, 如果你真的這麼做的話,ASP.NET 網站就會掛給你看,並出現 Service Unavailable 的錯誤訊息。

 Service Unavailable

如果你在事件檢視器中查詢錯誤紀錄,你就會查到以下訊息:

應用程式集區,'DefaultAppPool' 的識別項無效。當處理應用程式集區的第一個要求時,如果它仍然無效,那麼應用程式集區將被停用。資料欄位含有錯誤號碼。

以及

應用程式集區 'DefaultAppPool' 的識別項無效,因此 World Wide Web Publishing 服務無法建立工作者處理序,以處理應用程式集區。所以已停用應用程式集區。

所以光是這樣設定是不行的,以下就是正確設定的標準作業流程(SOP):

  1. 新增使用者
  2. 將該使用者加入 IIS_WPG 群組
  3. 修改系統暫存目錄 ( C:\WINDOWS\Temp ) 權限,讓該使用者可讀、可寫
  4. 修改應用程式集區身份識別設定,並設定為該使用者

備註一:IIS_WPG 群組是從 IIS 6.0 才加入的,最主要的目的就在於提供一個最小的執行權限,專門用來啟動工作處理程序(Worker Process)用的,所以如果你新建立的使用者不屬於 IIS_WPG 群組的話,工作者處理序就會無法啟動,這也是因為 ASP.NET 會回應 Service Unavailable 的主因。

備註二:關於系統暫存目錄 ( C:\WINDOWS\Temp ) 權限應該是不用設定到可讀、可寫這麼大,因為我查詢我的伺服器上的 C:\WINDOWS\Temp 目錄對於 NETWORK SERVICE 的預設設定,原來只要有「列出資料夾/讀取資料」與「刪除」兩種權限就可以正常運行 ASP.NET 了。

檢視/設定使用者詳細權限(進階安全性設定)的方法如下:

C:\WINDOWS\Temp 內容

C:\WINDOWS\Temp 的進階安全性設定

 C:\WINDOWS\Temp 的權限項目

備註三:預設 IIS_WPG 群組可對 Temporary ASP.NET Files 進行讀寫,所以無須修改此目錄的權限。
    預設路徑為 C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\Temporary ASP.NET Files

預設 IIS_WPG 群組可對 Temporary ASP.NET Files 進行讀寫

---

今天是 2008 年的最後一天,我今年共發表了 368 篇文章,部落格一整年的瀏覽人次也突破 35 萬人次,感覺還蠻不錯的。我這一整年的收穫,除了自己的技術不斷精進外,也幫助不少人充實技術觀念、開發技巧或實務經驗,當然也認識了一堆未曾蒙面的技術同好,這些對我來說都是無價之寶。

接下來幾天難得的年假我會好好休息(不碰電腦),所以可能會有幾天沒有文章,期望沈澱之後能夠繼續堅持下去,不斷的透過部落格激勵自己成長茁壯。

在此也預祝各位 2009 新年快樂! ^_^

相關連結

  

此文章由 will 發表於 2008/12/31 下午 08:57:52

永久連結 | 評論 (0) | 此文章的RSSRSS comment feed |

分類: IIS | 系統管理

標籤: , , ,

收藏:

介紹好用工具:如何製作可開機 USB 隨身碟

今天又再次遇到需要製作 USB 開機磁碟的需求,我再把我之前的筆記翻出來,趁機也發表在部落格中,我只列出最精簡的步驟。

總共有 7 個步驟:

  1. 下載 Windows-based Format Utility for HP DiskOnKey USB Device 工具程式

  2. 執行 SP27213.exe 安裝檔,預設會有兩個執行檔會安裝到 C:\DriveKey 目錄下:

    1. HPUSBF.EXE
      DOS Command-line 工具程式
    2. HPUSBFW.EXE
      Windows格式化USB磁碟工具

  3. HPUSBFW.EXE 透過 7-zip 或其他解壓縮工具解壓縮到任意目錄下
    備註1:該目錄裡面含DOS開機程式
    備註2:假設我們解壓縮到 C:\DriveKey\HPUSBFW 目錄下,如下圖示:

    將 HPUSBFW.EXE 透過 7-zip 或其他解壓縮工具解壓縮到任意目錄下 

  4. 執行 HPUSBFW.EXE 程式,並設定 USB 的 Volume label 與 Format options

    重點是你若要讓 USB 隨身碟可開機的話,必須勾選 Create a DOS startup disk 並設定 using DOS system files located at 欄位,指定到步驟 3 解壓縮的目錄,例如:C:\DriveKey\HPUSBFW

    HP USB Disk Storage Format Tool, V2.0.6

    之後畫面會提示你該 USB 磁碟中的資料會全部被清除掉,按下 是(Y) 就可以格式化完成:

    HPUSBFW: WARNING! ALL DATA ON THE UFD \92D (126 MB) (H:\) DEVICE WILL BE LOST! Do you really REALLY want to proceed with Format?
  5. 接著為了讓 USB 開機磁碟可以支援 CD-ROM 讀取,還必須複製 C:\DriveKey\HPUSBFW 目錄下的一些檔案到 USB 磁碟中,如下檔案:

    ANSI.SYS
    CHOICE.COM
    COMMAND.COM
    EMM386.EXE
    HIMEM.SYS
    MSCDEX.EXE
    OAKCDROM.SYS
    RAMDRIVE.SYS

    注意:該目錄下的 IO.SYS 與 MSDOS.SYS 是系統檔案,不能再複製進去蓋掉。

  6. 建立一個 CONFIG.SYS 設定檔,檔案內容如下:

    DEVICE=HIMEM.SYS
    DEVICE=EMM386.EXE NOEMS
    DEVICEHIGH=OAKCDROM.SYS /D:MSCD001
    DOS=HIGH,UMB
    FILES=30
    BUFFERS=30
    LASTDRIVE=Z
  7. 建立一個 AUTOEXEC.BAT 批次檔,檔案內容如下:

    LH MSCDEX.EXE /D:MSCD001

之前也是研究了好久,這應該是最精簡的步驟了,而且只需要下載一個檔案而已。

相關連結

  

此文章由 will 發表於 2008/12/30 下午 10:44:46

永久連結 | 評論 (8) | 此文章的RSSRSS comment feed |

分類: 介紹好用工具 | 系統管理

標籤:

收藏:

如何在 C# 中使用關鍵字當屬性名稱 ( ASP.NET MVC )

最近在看 Oxite 原始碼的時候,發現一段有趣的程式碼,感覺很像 Perl 的陣列,但我從未在 C# 程式中看到有人這麼用,如下範例:

<%= Html.TextBox("username", Request["username"], 
       new { 
          id = "login_username", 
          @class = "text", 
          tabindex = "1", 
          title = Localize("Your username...")
       }
   ) %>

我覺得奇怪的地方是在 Html.TextBox 第三個參數的地方用的雖然是一個匿名型別,但有個屬性設定時竟然是 @class 耶,第一眼看到的感覺是「好奇怪」的寫法,難道又是什麼未公開的密技嗎?因為我從未這樣寫過。

這段程式是 ASP.NET MVC 的 View 常用的一個 HTML Helpers 寫法,因為 ASP.NET MVC 的 View 經常需要透過 HTML Helpers 輸出標籤或表單欄位,而在設定時經常需要設定額外的 HTML 屬性(Attributes),所以才需要第三個參數設定,但是若要設定 HTML 中的 class 屬性時,就遇到大災難了!因為 class 是 C# 關鍵字(保留字),照裡說不能出現在屬性、欄位、方法、變數名稱中。

查證得知,原來在 C# 中還是可以使用保留字當識別名稱,只要前面加上一個小老鼠符號 ( @ ) 即可!

這個技巧對於 ASP.NET MVC 開發人員來說非常的重要,不然每次用 HTML Helper 時都不能設定 class 屬性時,心中的怒火應該會越燒越旺!^_^

相關連結

  

此文章由 will 發表於 2008/12/29 上午 02:25:26

永久連結 | 評論 (1) | 此文章的RSSRSS comment feed |

分類: ASP.NET | C# | ASP.NET MVC

標籤: ,

收藏:

ASP.NET 如何動態載入組件(Assembly)

如果你的 IIS 中有許多相關站台、網站、或 Web,但每個不同的網站都會使用到相同組件的話,通常的作法是將該組件註冊進 GAC ( Global Assembly Cache )。我最近就在想有沒有辦法就將組件放在特定目錄下,然後所有的 ASP.NET 就動態載入這個目錄中的特定幾個共用的組件,以下是研究的心得分享。

我將整個過程分成「開發階段」與「部署階段」,並假設以下情境:

  • 假設共用的組件檔名為 "ShareCL.dll"。
  • 部署階段時要將 ShareCL.dll 放一份到特定目錄下,假設共用的目錄為 "D:\ShareDLL\"。

開發階段

在開發階段的時候,那些共用的組件一樣放到各專案的 bin 目錄下,所以在 Visual Studio 中開發的時候,一樣可以享用 Intellisense 的好處,整個開發過程就跟平常開發時一樣。

但由於我們將網站部署到正式主機時,組件並不在各網站的 bin 目錄下,而是在共用的目錄裡,這時就會發生組件解析失敗的錯誤:

無法載入檔案或組件 'ShareCL, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' 或其相依性的其中之一。 系統找不到指定的檔案。

我們只要修改 Global.asax 的 Application_Start() 事件中的程式碼,告訴 AppDomain 在解析/找尋組件失敗的時候,要特別去我指定的地方載入共用的組件,我們要靠的是 AppDomain.AssemblyResolve 事件:

protected void Application_Start() {
    AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler(MyAssemblyResolver);
}

static Assembly MyAssemblyResolver(object sender, ResolveEventArgs args) {
    AppDomain domain = (AppDomain)sender;
    byte[] rawAssembly = System.IO.File.ReadAllBytes(@"D:\ShareDLL\ShareCL.dll");
    byte[] rawSymbolStore = System.IO.File.ReadAllBytes(@"D:\ShareDLL\ShareCL.pdb");
    Assembly assembly = domain.Load(rawAssembly, rawSymbolStore);
    return assembly;
}

加上這段程式碼之後,當網站應用程式找不到我們的共享組件時,就會自動到 D:\ShareDLL\ShareCL.dll 動態載入組件了,而且也只有「找不到」組件時才會執行這個事件方法,因此並不會影響開發作業。

部署階段

部署網站時就可以不用再針對每個網站更新 bin 目錄下的組件了,只要將組件更新到共享的組件目錄中即可。

不過由於組件是在 Application-Level 載入的,所以就算你更新了網站中的組件,事實上也不會立即生效,而是當應用程式重新啟動時才會重新載入更新過的組件,這部分可以透過重新啟動 IIS 中的應用程式集區(Application Pool)即可達到此需求。

如果你想列出目前 AppDomain 所載入的組件有哪些,可以用以下程式碼取得:

Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();

foreach (Assembly assembly in assemblies)
{
    Response.Write(assembly.FullName + "<br/>");
}

相關連結

  

此文章由 will 發表於 2008/12/28 下午 09:49:19

永久連結 | 評論 (6) | 此文章的RSSRSS comment feed |

分類: .Net | ASP.NET

標籤: ,

收藏:

介紹好用工具:Menu Editor (整理 Firefox 選單項目的好幫手)

Menu Editor 是一個 Firefox 瀏覽器的一個外掛元件(或稱附加元件)(Add-ons),這個工具最主要的功能就是可以讓你自訂編輯所有 Firefox 的主要選單(Main Menu)與頁面右鍵選單(Context Menu),他的編輯功能可以讓你決定「選單項目出現的順序」或「選單項目要顯示或隱藏」,可以讓你完全自訂選單項目的顯示。

Firefox Add-ons - Menu Editor Options

在用 Firefox 時應該多少會安裝些附加元件(Add-ons)吧,但越裝越多之後應該會發現在頁面按滑鼠右鍵的選單會越來越多東西,像我自己是還蠻節制的,盡可能的只安裝常用的附加元件,不過剛剛計算了一下右鍵選單(Context Menu)還是有 23 個項目,這時透過 Menu Editor 這個外掛程式就很適合了,把一些不常用的項目隱藏起來。

至於使用方式可以參考這篇文章的說明。

相關連結

  

此文章由 will 發表於 2008/12/27 下午 11:55:19

永久連結 | 評論 (0) | 此文章的RSSRSS comment feed |

分類: 介紹好用工具

標籤: ,

收藏: