如何對組態區段加密

0 comments
在 ASP.NET 2.0 中,你可以用 Configuration APIs 對 web.config 中的敏感性資訊(如使用者名稱、密碼、連線字串和加密金鑰等)進行加密保護,以提升應用程式的安全性。不過,你可以使用更簡單的 Aspnet_regiis.exe 工具來完成加密處理。當要求網頁時,ASP.NET 會自行將加密的組態資訊解密,讓應用程式使用。所以,你不需要撰寫額外的程式碼來讀取加密過的組態資訊。

接下來,將以 connectionStrings 區段為例,提供逐步指引來說明如何使用 Aspnet_regiis.exe 加密組態資訊。

  1. 先將 ASP.NET 應用程式檔案部署到 Web 實際執行伺服器(Production Server)。
  2. 在 IIS 中建立 ASP.NET 網站:
    1. 打開 IIS 管理主控台。
    2. 展開本機電腦節點,接著展開 [網站],建立新的網站。
    3. 點選 [ASP.NET] 頁簽,將 ASP.NET 版本設為 2.0.*。若無該頁簽,則到 [主目錄] 頁簽,按下 [設定] 按鈕,在 [對應] 索引標籤上,將 ASP.NET 相關應用程式副檔名對應的應用程式指向 %WINDIR%\Microsoft.NET\Framework\v2.0.*\aspnet_isapi.dll。
  3. 建立 RSA 金鑰容器(Key Container):
    1. 打開 Web 應用程式根目錄的 web.config,修改成實際執行的連線字串。
    2. 在 [執行] 對話方塊中的 [開啟] 方塊中,鍵入 cmd,然後按下 [確定] 。
    3. 建立名為 NetFrameworkConfigurationKey 的電腦層級 RSA 金鑰容器,請在命令提示字元中執行下列命令:
      %WINDIR%\Microsoft.NET\Framework\v2.0.*\aspnet_regiis.exe -pc "NetFrameworkConfigurationKey" -exp
    4. 授予 ASP.NET 使用者識別(在 Windows Server 2003 的電腦上,預設為 NETWORK SERVICE 帳戶)能讀取這個金鑰容器的權限,請執行下列命令:
      C:\WINDOWS\Microsoft.NET\Framework\v2.0.*\aspnet_regiis.exe -pa "NetFrameworkConfigurationKey" "NT AUTHORITY\NETWORK SERVICE"
  4. 加密 connectionStrings 區段:
    1. 請在命令提示字元中執行下列命令:
      C:\WINDOWS\Microsoft.NET\Framework\v2.0.*\aspnet_regiis.exe -pef connectionStrings %路徑%
    2. 如果需要修改連線字串,可以用如下的指令解密:
      C:\WINDOWS\Microsoft.NET\Framework\v2.0.*\aspnet_regiis.exe -pdf connectionStrings %路徑%

參考資料:
逐步解說:使用受保護的組態加密組態資訊 by Microsoft
逐步解說:建立和匯出 RSA 金鑰容器 by Microsoft

繼續閱讀...

Response.End() Exceptions in ASP.NET

1 comments
如果你在 ASP.NET 使用 Response.End 時,就會發生ThreadAbortException 例外狀況。舉例來說,當你在 try - catch 陳述式中,呼叫 Response.End 時,就會引發例外狀況:「System.Threading.ThreadAbortException: 執行緒已經中止」。

其實,當你使用 Response.End 方法時,會因為內部呼叫 Thread.Abort() 而引發 ThreadAbortException 的例外,停止網頁的執行,略過 Response.End 以下的程式碼,並將緩衝輸出的資料傳送到用戶端,然後才直接觸發 HTTP 管線(HTTP Pipelines)的執行鏈結裡的最後一個事件,也就是 HttpApplication.EndRequest 事件。而使用 Response.Redirect 或是 Server.Transfer 也會發生這種例外,因為這兩個方法都會在內部呼叫 Response.End 方法。

解決方案
當了解事實真相後,問題就已不再是"問題"了,而是端看你如何正確的應用。事實上,你無須介入處理 Response.End 所引發的例外狀況,也就是不要把 Response.End 放在 try 區塊中,況且使用 try - catch 陳述式也會比較消耗系統資源,應該斟酌使用。想了解更多例外狀況有關的效能問題,可以參考這裡這裡

如果你需要在執行 Response.End、Response.Redirect 或 Server.Transfer 方法之後,仍能繼續執行程式碼,可使用下列作法:
  • 使用 HttpContext.Current.ApplicationInstance.CompleteRequest 方法取代 Response.End 。
  • 對於 Response.Redirect(url),使用 Response.Redirect(url, false),要求不要結束目前網頁的執行,也就是呼叫 Response.End 方法。
  • 使用 Server.Execute 方法代替 Server.Transfer。

HttpApplication.CompleteRequest 跟 Response.End 有何不同呢?
對於 HttpApplication.CompleteRequest 的用途,在 MSDN 文件所得到的解釋如下:
造成 ASP.NET 略過 HTTP 管線的執行鏈結裡的所有事件和篩選,並且直接執行 EndRequest 事件。
事實上,如果你是在網頁的 Page_Load 事件處理常式中執行 HttpApplication.CompleteRequest 的話,ASP.NET 仍會處理完 PostBack 所引發的事件,然後才略過其他事件而直接執行 Application_EndRequest 事件。但同樣的狀況,若是改用 Response.End,就會直接結束目前網頁執行,而無法處理 PostBack 所引發的事件。想了解更多關於應用程式與網頁的事件觸發順序,可以參考這裡

參考文章:
PRB: ThreadAbortException Occurs If You Use Response.End, Response.Redirect, or Server.Transfer by Microsoft
Response.Redirect(url) ThreadAbortException Solution by John S. Reid

繼續閱讀...