日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 >

FineUI(开源版)v6.0中FState服务器端验证的实现原理

發布時間:2025/4/16 40 豆豆
生活随笔 收集整理的這篇文章主要介紹了 FineUI(开源版)v6.0中FState服务器端验证的实现原理 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

前言

1. FineUI(開源版)是完整開源,最早發起于 2008-04,下載全部源代碼:http://fineui.codeplex.com/

2. 你可以通過捐贈作者來支持FineUI(開源版)的發展:http://fineui.com/donate/

?

FineUI的FState與ViewState

早在2013-01 我曾寫過一篇文章,對FState有詳細介紹:http://www.cnblogs.com/sanshi/archive/2013/01/08/2850459.html

現在來簡要回顧一下:

1. ViewState是ASP.NET WebForm的基石,用來在頁面回發過程中維持控件狀態,這樣我們才能在后臺方便的使用控件的服務器端屬性。

2. FineUI的AJAX回發過程中,相同的數據會同時存在于ViewState和返回的JavaScript代碼中,造成數據重復浪費!

3. FState機制替換ViewState后,只會在回發數據中保留一份數據,減少了數據的傳輸量。

?

對于,常見的誤解與糾正:

1. FineUI中不能使用ViewState了。錯!!

???? FineUI只是實現了一套類似ViewState的機制,但是ViewState本身還是存在的,你依然可以在頁面上調用ViewState對象存儲數據。

2. 不使用ViewState了,FineUI控件不能維持狀態了。錯!!

???? FState是在AJAX環境中對ViewState的一種改進和提高,目的是為了減少數據傳輸量。你依然可以方便在C#代碼中使用控件屬性

?

FineUI中的FState可以被惡意篡改

FState用來在頁面回發過程中維持控件的狀態,但是由于FState完全以JavaScript變量的形式暴露出來,很容易被惡意用戶在客戶端進行篡改。

首先來看一個簡單的頁面:

<f:PageManager ID="PageManager1" runat="server" /> <f:DropDownList runat="server" ID="DropDownList1"><f:ListItem Text="可選項1" Value="Value1" Selected="true" /><f:ListItem Text="可選項2" Value="Value2" /><f:ListItem Text="可選項3" Value="Value3" /> </f:DropDownList> <f:Button runat="server" Text="提交" ID="btnSubmit" OnClick="btnSubmit_Click"></f:Button>

后臺的按鈕事件:

protected void btnSubmit_Click(object sender, EventArgs e) {Alert.Show("下拉列表選中項:" + DropDownList1.SelectedValue); }

頁面運行效果:

在頁面生成的HTML代碼,我們可以看到 f_state 的身影:

?

下面我們通過一個例子來講解 FState 的作用,假如用戶在前臺對下拉列表的數據進行了重新綁定:

var ddl = F("DropDownList1"); var newdata = [["Data1", "數據1", 1],["Data2", "數據2", 1],["Data3", "數據3", 1] ]; ddl.store.loadData(newdata); ddl.setValue("Data1");

此時點擊提交按鈕,效果:

之所以后臺取不到下拉列表的選中值,是因為后臺從FState恢復了下拉列表的項分別是“選項一”,“選項二”和“選項三”。

而對于客戶端重新綁定的新數據源,后臺一無所知,因此拿新的選中項值 Data1 去檢索時,自然就找不到對應的項了,所以此時SelectedValue==null

?

這個邏輯自然是正確的,但是由于 FState 是以JavaScript的形式返回到頁面的,所以惡意用戶自然就可以篡改這個值了:

var ddl = F("DropDownList1"); var newdata = [["Data1", "數據1", 1],["Data2", "數據2", 1],["Data3", "數據3", 1] ];ddl.f_state.F_Items = newdata; ddl.store.loadData(newdata); ddl.setValue("Data1");

此時再點擊提交按鈕:

此時服務器已經接受了這個客戶端惡意篡改的值!!這個就不對了。

?

如果是文本輸入框的值,我們自然是要手工進行服務器端驗證的,不要相信客戶端傳入的任何值,因為都有可能被篡改!

但是如果能默認提供一種內置的驗證機制,讓這種惡意修改FState的行為消失,豈不是更好。FineUI v6.0對此進行了增強。

?

FineUI v6.0 中默認的FState服務器端驗證

完全相同的例子,在 FineUI v6.0 中,如果通過客戶端修改下拉列表的f_state和內部數據,此時提交按鈕:

?

這個就是我們的保護機制,保護服務器端輸出的FState信息不會在客戶端被惡意修改。

那么這種保護機制是如何實現的呢?我們從生成的網頁代碼來分析一下:

?

可以看到,控件除了生成 f_state 屬性,還額外附加了一個 f_state_v 屬性,這個很容易理解為對 f_state 的加密值。

那么在頁面回發時,只需要把這個 f_state_v 的值一塊回發,后臺進行解密驗證即可。我們來看下HTTP請求的參數:

這里沒有 f_state_v 的身影,那是因為他隱藏在 F_STATE 變量中的,這個值是 Base64 編碼的,我們解碼后看下:

{"DropDownList1": [{"F_Items": [["Data1", "\u6570\u636e1", 1],["Data2", "\u6570\u636e2", 1],["Data3", "\u6570\u636e3", 1]],"SelectedValue": "Value1","SelectedValueArray": ["Value1"]}, "e1ae24"] }

可以看到,這個 f_state_v 的確一起回發到后臺了。

這個邏輯其實并不復雜:

1. 頁面初始化時,除了生成控件的 f_state 之外,還額外的生成一個加密后的信息 f_state_v

2. 頁面回發時,后臺把這兩個值進行校驗,就知道是否在客戶端被修改了

3. 如果后臺控件的屬性發生變化,還重新生成 f_state_v 更新到前臺

?

這里給出后臺的主要邏輯代碼,完整源代碼請自行下載:

private static string GetFStateValidation(JObject stateObj) {string fstate = stateObj.ToString(Newtonsoft.Json.Formatting.None);return GetShortMD5HashWithSeed(fstate); }private static bool ValidateFState(JObject stateObj, string validationString) {string fstate = stateObj.ToString(Newtonsoft.Json.Formatting.None);string fstateCode = GetShortMD5HashWithSeed(fstate);if (fstateCode == validationString){return true;}else{return false;} }private static string GetShortMD5HashWithSeed(string fstate) {string md5HashStr = StringToMD5Hash(fstate + GetFStateValidationSeed());return md5HashStr.Substring(0, 3) + md5HashStr.Substring(md5HashStr.Length - 3, 3); }private static string StringToMD5Hash(string inputString) {MD5CryptoServiceProvider md5 = new MD5CryptoServiceProvider();byte[] encryptedBytes = md5.ComputeHash(Encoding.ASCII.GetBytes(inputString));string a = System.Text.Encoding.Default.GetString(encryptedBytes);StringBuilder sb = new StringBuilder();for (int i = 0; i < encryptedBytes.Length; i++){sb.AppendFormat("{0:x2}", encryptedBytes[i]);}return sb.ToString(); }private static string _fstateValidationSeed = String.Empty; private static string GetFStateValidationSeed() {if (String.IsNullOrEmpty(_fstateValidationSeed)){_fstateValidationSeed = new Guid().ToString();}return _fstateValidationSeed; }

?

小結

這篇文章講解了FineUI中的FState取代ViewState的原因,惡意用戶如何在客戶端篡改FState,然后介紹了FineUI v6.0對 FState 的保護機制。

然后我們從生成的頁面HTML入手,簡要分析了FState驗證機制的實現原理。

?

感興趣的朋友可以自行下載源代碼分析:http://fineui.codeplex.com/

?

關于開源和堅持

FineUI(開源版)開始于 2008-04,8年多時間內,我們堅持更新了 128 個版本,內部使用的 extjs 從最初的 v2.x,v3.x,到后來的v4.x,FineUI v6.0 使用了最新的extjs v6.2.0。

8 年間,我們看過太多的開源項目轟轟烈烈的來,平平淡淡的去,那些曾經熟悉的身影,曾經陪伴我們的代碼,都已經不復存在。其實很多時候,開源項目不是被新技術淘汰,而是被開源作者所丟棄,不免讓人扼腕嘆息。

每個存在都有存在的價值,時間總會讓之前的東西看起來不再那么新奇好玩,但是還有那么一幫曾經關注的網友,一直在使用的用戶,只有不斷的更新,才不會讓關心你的人失望。

?

?

任何事物的存在價值是無限的!

?

總結

以上是生活随笔為你收集整理的FineUI(开源版)v6.0中FState服务器端验证的实现原理的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。