ASP .NET 支援語音欄

表單驗證疑難排解

歡迎使用 ASP.NET 支援語音欄! 我的名稱是[身分遺值] Orman。 我在 Microsoft 工作超過 5 年,大部分的時間都集中在 Web 相關技術上,例如 Microsoft FrontPage 和新的 Microsoft SharePoint 技術。 我過去一年一直以支援工程師的身分與 Microsoft ASP.NET 合作。 這個月我將在 [支援語音] 欄中說明如何疑難排解 Microsoft ASP.NET 中的表單驗證。

表單驗證疑難排解

當您在 ASP.NET 應用程式中使用 Forms Authentication 時,您可能會發現必須疑難排解當使用者隨機重新導向至登入頁面時所發生的問題。 在理想世界中,這個問題的發生方式可讓您輕鬆附加偵錯工具並擷取問題。 但在生產環境中,這種情況很少發生。 若要疑難排解這類隨機發生的問題,您必須記錄與該問題相關的資訊,以便縮小根本原因。在此欄中,我們將簡要說明 Forms Authentication 概念。 接著,我們會調查哪些案例會導致使用者重新導向至登入頁面,以及如何擷取與隔離問題相關的資料。 我們也將說明如何實作 IHttpModule 介面來記錄 Forms 驗證資訊。

表單驗證概觀

當使用者使用 Forms Authentication 驗證至網站時,伺服器會建立 Cookie。 Cookie 的值是加密的表單驗證票證。 Cookie 會在每個要求傳遞給應用程式時傳送到伺服器,而 FormsAuthenticationModule 類別會解密 Cookie 值,並判斷使用者是否有效。根據預設,FormsAuthenticationModule 類別會新增至 Machine.config 檔案。 FormsAuthenticationModule 類別會管理 FormsAuthentication 程式。下列是來自 Machine.config 檔案的專案:

<httpModule>
     …other modules…
     <add name="FormsAuthentication"
         type="System.Web.Security.FormsAuthenticationModule" />
     …other modules…
</httpModule>

使用 Forms Authentication 進行驗證的一般 HTTP 流量看起來如下:

  1. 用戶端會將 HTTP GET 傳送到 Default.aspx。 不會傳送表單驗證 Cookie。

  2. 伺服器會傳送 302 回應 (將) 重新導向至 Login.aspx。

  3. 用戶端會傳送 HTTP POST 至 Login.aspx。 其中包含登入資訊。

  4. 伺服器會傳送 302 回應 (將) 重新導向至 Default.aspx。 表單驗證 Cookie 隨附在內。

  5. 用戶端會將 HTTP GET 傳送到 Default.aspx。 這包括表單驗證 Cookie。

如需實作及使用表單驗證的詳細資訊,請造訪下列 MSDN 網站:

HTTP://msdn2.microsoft.com/en-us/library/7t6b43z4.aspx

HTTP://msdn2.microsoft.com/en-us/library/system.web.security.formsauthentication (vs.71) .aspx

HTTP://msdn2.microsoft.com/en-us/library/system.web.security.formsauthenticationticket (vs.71) .aspx如需共用表單驗證 Cookie 的詳細資訊,請流覽下列 ASP.NET 網站:

HTTP://quickstarts.asp.net/QuickStartv20/aspnet/doc/security/formsauth.aspx

使用者可能重新導向至登入頁面的原因

表單驗證 Cookie 遺失

案例 1

在此案例中,使用者會登入網站。 在某些時候,用戶端會傳送要求到伺服器,而 FormsAuthenticationModule 類別不會收到 Cookie。 您可以啟用 Microsoft Internet Information Services (IIS) 中的 Cookie 記錄,判斷使用者要求是否不包含 Cookie。 若要這麼做,請遵循下列步驟:

  1. 開啟 MMC) (IIS Microsoft Management Console。

  2. 以滑鼠右鍵按一下網站,然後按一下 [ 內容]

  3. 按一下 [ 網站] 索 引標籤,然後按一下 [ 啟用記錄]

  4. 確定記錄格式為 W3C 延伸記錄檔格式

  5. 按一下 [內容]

  6. 按一下 [進階] 索引標籤,然後按一下 [ 延伸內容]

  7. 在 [ 延伸內容]底下,按一下以選取 [ Cookie (cs (Cookie) ) ] 核取方塊和 [ 參照者] (cs (Referer) ) 複 選框。

發生此問題之後,請判斷哪一個用戶端有問題,以及該客戶的 IP 位址。 篩選該用戶端 IP 位址上的 IIS 記錄檔,並檢視 <Cookie> 欄。注意 您可以使用記錄剖析器剖析 IIS 記錄。 若要下載 Log Parser,請造訪下列 Microsoft 網站:

HTTP://www.microsoft.com/download/details.aspx?FamilyID=890cd06b-abf8-4c25-91b2-f8d975cf8c07 當您有來自該特定使用者的要求清單之後,請搜尋登入頁面的要求。 您知道這些要求已重新導向至此頁面,而且您想要在重新導向之前看到要求。 如果您看到類似以下內容,表示用戶端並未傳送 Cookie,或是用戶端和伺服器之間的網路已移除 Cookie。這是初始登入。

方法

網頁

回應

Cookie

獲取

/Default.aspx

302 (重新導向)

無 Cookie

獲取

/Login.aspx

200 (Success)

無 Cookie

發佈

/Login.aspx

302 (重新導向)

無 Cookie

獲取

/Default.aspx

200 (Success)

.ASPXAUTH

獲取

/SomePage.aspx

302 (重新導向)

不。ASPXAUTH Cookie

這些是其他要求,後面接著要求至網站上的頁面,而沒有 。ASPXAUTH Cookie。

方法

網頁

回應

Cookie

獲取

/SomePage.aspx

302 (重新導向)

不。ASPXAUTH Cookie

獲取

/Login.aspx

200 (Success)

不。ASPXAUTH Cookie

發佈

/Login.aspx

302 (重新導向)

不。ASPXAUTH Cookie

獲取

/SomePage.aspx

200 (Success)

.ASPXAUTH

注意:除非您建立永續性 Cookie,否則該使用者的第一個要求不太可能有表單驗證 Cookie。 IIS 記錄只會顯示要求中收到的 Cookie。 成功登入之後,系統會提出第一個要求,要求使用表單驗證 Cookie。

案例 2

當用戶端的 Cookie 限制超過上限時,表單驗證 Cookie 也可能會遺失。 在 Microsoft Internet Explorer 中,Cookie 的限制為 20 個。 在用戶端上建立第 20 個 Cookie 之後,先前的 Cookie 會從用戶端的集合中移除。 如果 .ASPXAUTH Cookie 隨即移除,處理下一個要求時,使用者會重新導向至登入頁面。您可以用相同的方式疑難排解這兩個案例。 請在重新導向至登入頁面之前查看要求。 如果此頁面的要求產生 Cookie,這將會是要調查的事。您可以使用 Fiddler 來檢視傳送給用戶端的 HTTP 標頭。 擷取流量之後,按兩下要求,然後按一下 [標 ] 以查看 Set-Cookie 標頭。 如果您追蹤成功登入,您會在成功登入的回應中看到 Set-Cookie 標頭。若要下載 Fiddler,請造訪下列 Fiddler 網站:

HTTP://www.fiddlertool.com/fiddler/

狀況 3

要求離開用戶端之後,有各種圖層可能會影響傳送的封包。 若要判斷網路裝置是否正在移除 Cookie,您必須在用戶端和伺服器上擷取網路追蹤,然後查看 Cookie 要求的本文。 您想要查看用戶端要求以確定 Cookie 已傳送,並檢查伺服器追蹤以確定伺服器已收到 Cookie。用戶端要求 這是在使用者通過驗證之後的 GET 要求。 表單驗證票證資訊以藍色醒目提示。 這會確認 Cookie 資訊離開用戶端。 當您使用網路擷取工具時,例如 Netmon,您會看到實際經過轉接器的流量。

47 45 54 20 68 74 74 70-3a 2f 2f 6c 6f 63 61 6c   GET http://local
68 6f 73 74 2f 46 6f 72-6d 73 41 75 74 68 4c 6f   host/FormsAuthLo
67 54 65 73 74 2f 57 65-62 46 6f 72 6d 31 2e 61   gTest/WebForm1.a
73 70 78 20 48 54 54 50-2f 31 2e 31 0d 0a 41 63   spx HTTP/1.1..Ac
63 65 70 74 3a 20 69 6d-61 67 65 2f 67 69 66 2c   cept: image/gif,
…Other headers of the GET request…
63 68 65 0d 0a 43 6f 6f-6b 69 65 3a 20 2e 41 53   che..Cookie: .AS
50 58 41 55 54 48 3d 33-43 45 46 39 42 39 41 30   PXAUTH=3CEF9B9A0
43 33 37 41 44 46 36 33-45 36 42 44 33 37 42 36   C37ADF63E6BD37B6
39 43 44 41 32 35 30 30-30 46 38 30 37 32 38 46   9CDA25000F80728F
35 31 43 39 35 36 36 44-31 34 43 35 34 31 34 35   51C9566D14C54145
38 31 43 39 33 45 32 41-30 31 44 44 43 44 45 46   81C93E2A01DDCDEF
32 34 41 31 37 34 32 39-34 31 30 43 30 39 37 34   24A17429410C0974
42 33 45 43 42 30 36 34-32 32 38 45 33 35 33 39   B3ECB064228E3539
39 41 38 32 32 42 33 42-39 33 36 44 46 30 38 46   9A822B3B936DF08F
42 41 42 44 33 45 31 30-32 44 30 30 32 31 30 43   BABD3E102D00210C
32 45 31 33 39 38 30 37-39 42 32 33 35 32 39 46   2E1398079B23529F
34 46 35 44 37 34 41 3b-20 50 72 6f 66 69 6c 65   4F5D74A; Profile
3d 56 69 73 69 74 6f 72-49 64 3d 62 32 34 65 62   =VisitorId=b24eb

伺服器端要求 當您查看到達伺服器的要求時,您想要確認伺服器收到的用戶端所傳送的相同資訊。 如果伺服器未收到相同的資訊,您必須調查網路上的其他裝置,以判斷 Cookie 移除的位置。注意:也有 ISAPI 篩選器正在移除 Cookie 的實例。 如果您確認網頁伺服器已收到 Cookie,但 Cookie 未列在 IIS 記錄中,請檢查 ISAPI 篩選。 您可能必須移除篩選,才能查看問題是否已解決。

表單驗證票證逾時

重新導向使用者的另一個常見原因是表單驗證票證已過期。 表單驗證票證有兩種方式可以逾時。 第一個案例會在您使用絕對過期時發生。 在絕對到期時,驗證票證會在到期日到期時過期。 例如,您將到期時間設定為 20 分鐘,而使用者會在下午 2:00 造訪網站。 如果使用者在下午 2:20 之後造訪網站,使用者將會重新導向至登入頁面。如果您使用滑動過期,則情況會比較複雜一些。 如果使用者在到期時間過半之後造訪網站,Cookie 和產生的票證就會更新。 例如,您使用滑動過期設定 20 分鐘的到期日。 使用者會在下午 2:00 造訪網站,而使用者會收到一個設定為將于下午 2:20 到期的 Cookie。 只有在使用者于下午 2:10 之後造訪網站時,才會更新到期日。 如果使用者在下午 2:09 造訪網站,則不會更新票證,因為有一半的到期時間尚未過。 如果使用者接著等候 12 分鐘,請于下午 2:21 造訪網站,票證將會過期。 使用者會重新導向至登入頁面。處理這類問題的方法之一是記錄表單驗證 Cookie 和票證資訊。 如此一來,您就可以查看 COOKIE 是否由 IIS 接收,以及值為何。 您可以撰寫 HttpModule,然後將該模組插入要求管線,藉此執行此動作。 您不需要修改應用程式的程式碼,就能取得所需的資訊。附加的範例適用于 Microsoft .NET Framework 1.1 和 .NET Framework 2.0,並具有整個批註。 範例包含下列檔案:

  • FormsAuthEvents.cs:實作 IHttpModule 並將其聯結到Application_BeginRequest事件的班級。

  • FormsAuthInfo.cs:擷取 Cookie 並解密表單驗證票證的班級。 它也會檢查應用程式的 Web.config 檔案,以確保已啟用表單驗證。

  • FormsAuthConfig.cs:從 FormsAuthLogger.config 檔案朗讀資訊的類別。

  • Log.cs:接受字串的檔案,並將值寫入記錄檔。

  • FormsAuthLogger.config:Log.cs 檔案讀取的 XML 檔案。 此檔案必須位於含有已建置 DLL 的 /bin 資料夾中。 此檔案可讓您設定下列專案:

    • 依 IP 篩選:您可以依用戶端 IP 篩選資料擷取。 如此一來,您只能記錄來自已知會重現問題之用戶端的要求。 這會縮減記錄檔的大小。

    • 擷取類型:這會指定儲存檔案的位置。 預設為 [暫存 ASP.NET 檔案] 資料夾,但只要工作人員程式帳戶能夠寫入資料夾,您就可以隨時隨地儲存此資料夾。

注意:我會提供 FormsAuthLogger.zip 檔案中所提供之程式碼的下載連結。我要在這裡指出主要區域:

  1. 建立可實作 IHttpModule 介面的班級。

    public class FormsAuthEvents : IHttpModule 
    {
    …code…
    }
  2. 連接您要查看的事件。 在這個範例中,我們使用Application_BeginRequest事件。 如此一來,我們就可以調查每個要求,並判斷它是否有表單驗證 Cookie,並在 Cookie 存在時記錄 FormsAuthenticationTicket。

    public void Init(HttpApplication application) 
    {
    //Wire up the BeginRequest event
    application.BeginRequest += (new EventHandler(this.Application_BeginRequest));
    }
  3. 實作Application_BeginRequest事件。

    private void Application_BeginRequest(Object source, EventArgs e)
    {
       …code to log the ticket…
    }
    
  4. 擷取表單驗證 Cookie,然後將它解密。

  5. 記錄值。 除了表單資訊之外,我建議您記錄下列內容。 這可協助您視需要將表單驗證資訊對齊 IIS 記錄檔:

    • 日期:可讓您查看要求何時送達。

    • RequestType:顯示要求是 [取得] 還是 [文章]。

    • URL:顯示導致問題的要求模式。

    • 引薦

    • ClientIP:要求與特定用戶端有關的關係。

Need more help?

Want more options?

探索訂閱權益、瀏覽訓練課程、瞭解如何保護您的裝置等等。

社群可協助您詢問並回答問題、提供意見反應,以及聆聽來自具有豐富知識的專家意見。