前言
在 ASP.NET 中,透過 URL 取得靜態檔案(例如: http://rm.com/download/d1.txt) 並不會透過 ASP.NET Handler 去處理,
所以當透過 Browser 直接輸入 URL 時,會直接依 IIS 中針對附檔名的設定,選取對應的處理常式(可查看 IIS 中的 處理常式對應)來處理,
預設是 StaticFile ,所以這些靜態檔案會依 IIS 中 MIME 的設定來決定在 Browser 直接顯示內容,還是下載檔案。
那要讓 TXT, XLS 等檔案在透過 URL 下載時,先驗證是否有登入系統才可下載要如何做呢?
當然是寫個客製化的 HttpHandler 來處理。
但是應用程式在 傳統模式 or 整合模式 的設定是不同的。
解法
1.建立客製化的 HttpHandler (FileProtectionHandler)
FileProtectionHandler 主要判斷使用者是否已登入(User.Identity.IsAuthenticated),如下,
1 | Public Class FileProtectionHandler |
註: Throw New HttpException(401, “Auth Failed”) ,您可以改成導到登入頁面
2.在 Web.Config 中註冊 FileProtectionHandler HttpHandler
2.1.應用程式集區為整合模式(Integrated Mode)
1 | <configuration> |
註1. WebApplicationVB為專案的 namespace,請依您專案的 namespace 調整
註2. 如果要 Handle 其他的靜態檔案,就再加入 path=”*.xlsx” 的 Handler 如下,
1 | <configuration> |
所以在 Browser 上輸入 d1.txt 就會被 FileProtectionHandler 處理到。
如果沒有登入,就會引發錯誤
註.3. 如果直接將應用程式切換成 傳統模式,就會出現 ManagedPipelineHandler 的錯誤
處理常式 “TxtHttpHandler” 的模組清單中有錯誤的模組 “ManagedPipelineHandler”
所以當應用程式使用的是 傳統模式,請使用以下的設定
2.2.應用程式集區為傳統模式(Classic Mode)
2.2.1.在 system.webServer 中的 handlers 區段,設定將 .txt 等靜態檔案,交由 aspnet_isapi.dll 來處理
1 | <configuration> |
註: 上面的 aspnet_isapi.dll 所使用.net版本,請依您專案使用的 .net 版本調整
2.2.2.在 system.web 中的 httpHandlers 區段,設定將 .txt 交由 FileProtectionHandler 來處理
1 | <configuration> |
註: 請注意,因為在 **傳統模式(Classic Mode) 是先將靜態檔案交由 aspnet_isapi.dll 處理,所以它會先走驗證通過後,才會進到我們寫的 FileProtectionHandler 之中
參考資料
How to: Register HTTP Handlers
Protect Static Files in ASP.NET Web Forms With the Help of HTTP Handler