iT邦幫忙

DAY 9
1

ASP.NET技巧系列 第 12

如何透過IHttpHandler讓某虛擬目錄中檔案(例如Test.txt)必須登入才可瀏覽(或下載)

我們有時候會有這樣的需求,有些檔案也會希望使用者能夠經過登入驗證後,才能下載使用。然而對於.NET的驗證機制來說,他所保護的是aspx等asp.net的相關檔案,如果您的檔案是【txt文字檔】、【zip壓縮檔】、【doc Word檔】等,這些的檔案只要知道超連結,就可以直接下載。

那麼有沒有辦法讓這些的檔案也能夠跟aspx一樣,當瀏覽的時候,就檢查看是否有登入系統,如果未登入,就直接倒向到使用者登入畫面,當登入完成後,再進行該檔案的瀏覽或下載。
運作原理

我們知道在aspx的檔案在ASP.NET的驗證機制下,如果輸入ABC.aspx,系統會自動導向到我們指定的登入畫面(例如:Login.aspx),當登入驗證完成後,會再次導向回剛剛想要瀏覽的網頁ABC.aspx。而這些的機制,都是透過.NET Framework的ISAPI 【aspnet_isapi.dll】來處理的。因此我們希望我們指定的副檔名也能夠透過【aspnet_isapi.dll】的處理,做出相同的動作。因此要處理三件事情。

1.撰寫IHttpHandler處理這些檔案類型
2.設定Web.Config來註冊IHttpHandler,並且設定該資料夾Deny Users="?"
3.在IIS中註冊這些副檔名由【aspnet_isapi.dll】處理(這樣才能啟動IHttpHandler)

首先要在自己的系統上建立.NET的驗證機制。

接著,在自己的ASP.NET專案中建立一個資料夾(Files),希望未來存放在此資料夾中的指定檔案格式需要驗證。

再專案中新增一個類別(Class),命名為CFileSafe.vb,Imports命名空間System.Web
接著在Class中Implements IHttpHandler,VS自動會產生IsReusable的Property與ProcessRequest的Sub,接著撰寫處理Request的內容,判斷傳入的副檔名,依據不同的副檔名,指定不同的Response.ContentType,相關的程式內容如下:

Imports Microsoft.VisualBasic 
Imports System.Web 
 
Public Class CFileSafe 
    Implements IHttpHandler 
 
    Public ReadOnly Property IsReusable() ReadOnly Property IsReusable() As Boolean Implements System.Web.IHttpHandler.IsReusable 
        Get 
 
        End Get 
    End Property 
 
    Public Sub ProcessRequest() Sub ProcessRequest(ByVal context As System.Web.HttpContext) Implements System.Web.IHttpHandler.ProcessRequest 
        Dim FileName As String = context.Request.FilePath 
        Dim tmpS() As String 
        tmpS = FileName.Split(".") 
        Dim FileExten As String = LCase(tmpS(UBound(tmpS))) 
        Dim GetContentType As Boolean = False 
        Select Case FileExten 
            Case "txt" 
                context.Response.ContentType = "text/plain" 
                GetContentType = True 
            Case "doc" 
                context.Response.ContentType = "application/msword" 
                GetContentType = True 
            Case "xls" 
                context.Response.ContentType = "application/ms-excel" 
                GetContentType = True 
            Case "ppt" 
                context.Response.ContentType = "application/vnd.ms-powerpoint" 
                GetContentType = True 
            Case "pdf" 
                context.Response.ContentType = "application/pdf" 
                GetContentType = True 
            Case "zip" 
                context.Response.ContentType = "application/x-zip-compressed" 
                GetContentType = True 
            Case "gif" 
                context.Response.ContentType = "image/gif" 
                GetContentType = True 
 
            Case "tif" 
                context.Response.ContentType = "image/tiff" 
                GetContentType = True 
 
            Case "jpg" 
                context.Response.ContentType = "image/jpeg" 
                GetContentType = True 
 
        End Select 
        If GetContentType Then 
            context.Response.TransmitFile(context.Request.FilePath) 
            'context.Response.Write(FileExten) 
        Else 
            'context.Response.Write(FileExten) 
            context.Response.Write("未設定檔案格式【" & FileExten & "】!!") 
        End If 
 
    End Sub 
End Class 

接著要針對此資料夾(Files)增加一個Web.config來註冊IHttpHandler,順便指定此資料夾不允許未登入使用者存取

    <system.web> 
      <httpHandlers> 
        <add verb="*" path="*.*" type="CFileSafe"/> 
      </httpHandlers> 
      <authorization> 
        <deny users="?"/> 
      </authorization> 
    </system.web> 

程式的部分就到此為止,接著就可以放些測試的檔案到此資料夾中,並且拉出超連結到Login.aspx中,方便測試登入的驗證。

此時執行Login.aspx,點選超鏈結到Test.txt,卻發現還是沒有要求登入就直接顯示?原因是我們還少了最後的一個步驟→設定這些檔案格式給ISAPI處理

開啟IIS,瀏覽到我們ASP.NET應用程式中的Files資料夾,點選滑鼠右鍵→內容。
當我們要設定ISAPI的時候發現,由於他不是個應用程式,所以無法針對Files設定ISAPI

此時我們可以先暫時把該資料夾建立為應用程式,讓他可以設定,等設定完成後再把應用程式移除即可。


接著進入設定,來看看副檔名aspx的設定為何??

將處理aspx的aspnet_isapi.dll路徑複製下來,等一下用相同的檔案來處理我們要處理的副檔名

接著新增一個副檔名的處理,我們舉txt來當作範例


接著把其他的副檔名用相同的方式設定,這個部份的畫面就省略了。
最後,Files其實不是個應用程式所以記得把應用程式移除

經過以上的設定後,再來測試看看就會發現,當瀏覽Files下的Test.txt的時候,系統會自動導向到Login.aspx要求登入,登入完成後,自動再導回Test.txt的內容進行瀏覽。接著測試zip也一樣,在未登入的狀況下,會要求使用者進行登入,登入完成後,就會出現下載儲存的對話方塊。


上一篇
ObjectDataSource簡介Part1:兼具ADO.NET的自由與DataSource的方便
下一篇
GridView點選Row任何位置就選擇Part2
系列文
ASP.NET技巧17

尚未有邦友留言

立即登入留言