Asp.Net Forms認證在移動平台中遇到的一個問題以及調查過程


我們項目的網站的移動版是基於Asp.Net平台開發的,用戶登錄也是基於Asp.Net的Forms認證,在整個開發和測試過程中沒有發現任何客戶登錄異常,但是發布后斷斷續續有用戶反映在登錄頁面登錄成功后跳轉主頁后,主頁並沒有識別登錄用戶,也即是Form 認證失敗。Asp.Net的Form認證大家應該有所了解,其內部的機制就是把用戶數據加密后保存在一個基於cookie的票據FormsAuthenticationTicket中,即認證過程中要借助於cookie。初步判斷問題出在cookie上,以下是問題的調查過程。

搭建調試環境

移動平台web開發中,調試不像桌面web開發中那么容易,難點在於移動設備多種多樣,並且移動設備中也很少有幫助調試的工具。為了測試如上的問題,我們借助了一個強大的HTTP監控工具Fiddler。 Fiddler可以設置容許遠程設備通過代理訪問服務器,這樣Fiddler就可以監控移動設備中的HTTP請求。Fddler中的設置如下圖:

image

設置移動設備的網絡訪問代理為Fiddler所在的機器IP,端口為如上圖所示Fiddler設置監控的端口號,這樣就可以監控移動的所有HTTP的請求了。

確定問題點

搭建好測試環境后,就開始確認問題了,用戶無法登陸,那么是否cookie丟失了呢? 認證的cookie是在登錄畫面設置的,登錄畫面的請求是通過HTTPS協議的,而首頁的請求是通過HTTP協議的,通過查看Fiddler,用戶登錄后,登錄頁面成功設置了認證cookie,並且首頁請求時也把認證cookie發回到了服務器端,監控信息如下圖顯示:

登錄畫面設置的cookie

image

首頁發回到服務器端的cookie

image

至此可以判斷,問題不是在客戶端,而是在服務器端,那么為什么服務器端不能識別返回的認證信息呢?為什么有些從某些設備上登錄就失敗呢?這些設備的瀏覽器發到服務器端的請求唯一的差別就是user-agent,那么服務器端針對user-agent又做了些什么呢?帶着這些問題,又深入地研究了一下ASP.NET認證原理,以及ASP.NET中有關cookie方面的一些特性。

深入理解cookieless在ASP.NET Form認證中的應用

要確認服務器端為什么沒有成功認證,那么必須要理解ASP.Net中的cookieless功能。

cookie失效有很多原因,有用戶禁用cookie的,也有設備不支持cookie的,所以ASP.NET中加入了cookieless這樣一個特性,使得當cookie失效是也能提供一種類似cookie的作用,比如可以把信息通過URL傳遞,cookieless這個功能就是基於這樣的目的而加入的。

cookieless總共有四種模式:

1,”UseCookies”,即cookieless功能不啟用

2,”UseUri”,即cookieless功能對所有設備啟用

3,”UseDeviceProfile”,根據發起請求的瀏覽器來確定應用或者不應用Cookieless,如果ASP.NET識別瀏覽器不能夠支持cookies,那么就啟用cookieless功能。另外從技術上說,如果瀏覽器支持cookie,那么如下兩個屬性的值為true:Request.Browser.CookiesRequest.Browser.SupportsRedirectWithCookie。

4, “AutoDetect”,從直接意思上理解,就是由ASP.NET來檢測當前瀏覽器是否支持cookies,這個模式有些迷惑用戶,並且也較復雜,官方文檔上有解釋這種模式的偽代碼

以上模式中UseDebiceProfile和AutoDetect模式依賴於設備,ASP.NET在維護一份數據庫,這份數據庫一般保存在如下的路徑中:%WINDIR%\Microsoft.Net\Framework\v2.0.50727\CONFIG\Browsers,數據庫中保存有已知的各種設備的兼容性,比如是否支持cookie,支持那些版本的javascript等等,從各種設備上的瀏覽器中發到服務器端的請求都會在HTTP頭中帶上特有的能標識設備的user-agent,ASP.NET就會自動根據user-agent到數據庫中比對,然后確定設備的兼容性。

這個cookieless功能也應用到了ASP.NET的Form認證中了,在web.config中的認證設置中可以配置cookieless屬性。默認情況下,Form 認證系統會根據發起請求的user agent來決定認證票是保存在cookie中還是包含在URL中,已知主流的桌面瀏覽器都是支持cookie的,但並不是所有移動版的瀏覽器都支持cookie。再次回到本篇文章所調查的bug中來,有些用戶不能正常登錄就是因為這些用戶所使用的設備被ASP.NET識別為不能支持cookie所致的,盡管設備本身是支持cookie的,比如我自己的手持設備MOTO Droid X,從這台設備的默認瀏覽器發出的請求中包含的user-agent為:User-Agent: Mozilla/5.0 (Linux; U; Android 2.3.3; zh-cn; DROIDX Build/4.5.1_57_DX5-18) AppleWebKit/533.1 (KHTML, like Gecko) H,/4.0 ��O�/533.1,經過ASP.NET識別為不支持cookie,所以這台設備無法正常登錄我們的web App。

以上我們調查清楚了登錄失敗的原因了,下面是給出具體的解決方案。

解決方案

明白了以上的Form認證原理,那么我們很容易想到,這是因為移動設備的user-agent無法被系統正確地識別而導致的cookie被禁用,這里有兩個解決方案:

方案1,覆蓋系統配置,讓所有的設備都能被系統識別為支持cookie。

Asp.NET提供了一種機制,讓我們可以自定義某些特定設備的系統支持,在工程中添加系統文件夾Asp_Browsers,並且添加自定義配置文件,如下是為了解決如上問題而添加的配置文件。

image

配置內容如下:

<browser refID="Mozilla" >
    <capabilities>
        <capability name="cookies"  value="true" />
    </capabilities>
</browser>

<browser refID="Default">
    <capabilities>
        <capability name="cookies" value="true" />
    </capabilities>
</browser>

如上的配置代碼表示,對所有的設備,都是支持cookies的,這樣就解決了某些設備上的cookies問題了。

 

方案2,更改form的默認設置,讓系統不再根據設備來判斷是否支持cookie

在站點的配置文件中有關於Form認證的配置,在配置<authentication mode="Forms">/<forms>中要加上cookieless="UseCookies",默認的配置是UseDeviceProfile,即工具設備來決定Cookies的支持。

以上兩種方案的目的是一樣的,即讓系統認為所有的設備都支持cookie,第一種更靈活,第二種解決問題更徹底,可以根據實際情況選擇合適的方案。

 

后記

微軟的cookieless設計本身是不錯,但是這個默認值為UseDeviceProfile是值得商榷的,如今的瀏覽器百花齊放,每個瀏覽器都有其特有的user-agent,尤其是移動版的瀏覽器,即使是相同的瀏覽器,不同的設備制造商也會在user-agent加上標識設備型號和品牌的信息,微軟又不可能頻繁更新ASP.NET維護的瀏覽器配置,所以就會出現大量的誤判情況。以目前的狀況,系統應該把默認值設置為UseCookies,即默認為所有的瀏覽器瀏覽器支持cookie。

參考文檔:

ASP.NET4中不要相信Request.Browser.Cookies,Form驗證要用UseCookies

Problem with Asp.Net Forms Authentication when using iPhone UIWebView

Forms Authentication Configuration and Advanced Topics (VB)

Understand How the ASP.NET Cookieless Feature Works


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM