【轉】Form驗證

Form驗證javascript

轉載:java

代碼寫 N 久了,總想寫得別的。這不,上頭說在整合兩個項目,作成單一登陸(Single Sign On),也有人稱之爲「單點登陸」。查閱相關文檔後,終於實現了,如今把它拿出來與你們一塊兒分享。或許你們會問:「這與標題不符呀?」別急,在下筆以前,我腦子裏想到了我剛使用 Form 認證時遇到的一些問題,以及使用過程用到的一些技巧(實乃投機取巧是也 ^_^ )。偶打初中那時,語文水平就不怎麼滴,考試經常做文寫不出來,因此寫做水平有限,還請你們海量。對了,本人不只寫做水平有限,編程能力也不是很好,此文供你們學習交流之用,歡迎廣大勞苦羣衆拎着雞蛋、捧着鮮花前來評論。轉載請註明原創做者乃寒羽楓是也,不甚感激!程序員

廢話也說的差很少了,言歸正傳, ASP.NET 的安全認證,共有「Windows」「Form」「Passport」「None」四種驗證模式。「Windows」與「None」沒有起到保護的做用,不推薦使用;「Passport」我又沒用過,唉……因此我只好講講「Form」認證了。我打算分三部分:web

第一部分——怎樣實現From 認證;數據庫

第二部分—— Form 認證的實戰運用;編程

第三部分——實現單點登陸(Single Sign On)c#

第一部分如何運用 Form 表單認證api

1、新建一個測試項目跨域

爲了更好說明,有必要新建一個測試項目(暫且爲「FormTest」吧),包含三張頁面足矣(Default.aspx、Login.aspx、UserInfo.aspx)。啥?有人不會新建項目,不會新增頁面?你問我咋辦?我看這麼辦好了:拖出去,打回原藉,從幼兒園學起……數組

2、修改 Web.config

一、 雙擊項目中的Web.config(不會的、找不到的打 PP)

二、 找到下列文字<authenticationmode="Windows"/> 把它改爲:

<authenticationmode="Forms">

<formslogi nUrl="Login.aspx"name=".ASPXAUTH"></forms>

</authentication>

三、 找到<authorization><allowusers="*"/></authorization>換成

<authorization><denyusers="?"></deny></authorization>

這裏沒什麼好說的,只要拷貝過去就行。雖然說如此,但仍是有人會弄錯,以下:

<authenticationmode="Forms">

<formslogin Url="Login.aspx"name=".APSX"></forms>

<denyusers="?"></deny>

</authentication>

若要問是誰把<denyusers="?"></deny>放入<authentication>中的,我會很榮幸地告訴你,那是 N 年前的我:<authentication>與<authorization>都是以auth字母開頭又都是以ation結尾,何其類似;英文單詞背不下來的我覺得他們是一夥的……

3、編寫 .cs 代碼——登陸與退出

一、 登陸代碼:

a、 書本上介紹的

private void Btn_Login_Click(object sender, System.EventArgs e)

{

if(this.Txt_UserName.Text=="Admin" && this.Txt_Password.Text=="123456")

{

System.Web.Security.FormsAuthentication.RedirectFromLoginPage(this.Txt_UserName.Text,false);

}

}

b、 偶找了 N 久才找到的

private void Btn_Login_Click(object sender, System.EventArgs e)

{

if(this.Txt_UserName.Text=="Admin" && this.Txt_Password.Text=="123456")

{

System.Web.Security.FormsAuthentication.SetAuthCookie(this.Txt_UserName.Text,false);

Response.Redirect("Default.aspx");

}

}

以上兩種均可發放驗證後的Cookie,即經過驗證,區別:

方法 a) 指驗證後返回請求頁面,俗稱「從哪來就打哪去」。好比:用戶沒登陸前直接在 IE 地址欄輸入http://localhost/FormTest/UserInfo.aspx,那麼該用戶將看到的是Login.aspx?ReturnUrl=UserInfo.aspx,輸入用戶名與密碼登陸成功後,系統將根據「ReturnUrl」的值,返回相應的頁面

方法 b) 則是分兩步走:經過驗證後就直接發放Cookie,跳轉頁面將由程序員自行指定,此方法多用於Default.aspx 使用框架結構的系統。

二、 退出代碼:

private void Btn_LogOut_Click(object sender, System.EventArgs e)

{

System.Web.Security.FormsAuthentication.SignOut();

}

4、如何判斷驗證與否及獲取驗證後的用戶信息

有的時候,在同一張頁面須要判斷用戶是否已經登陸,而後再呈現不一樣的佈局。有人喜歡用Session來判斷,我不反對此類作法,在此我只是想告訴你們還有一種方法,且看下面代碼:

if(User.Identity.IsAuthenticated)

{

//你已經過驗證,知道該怎麼作了吧?

}

User.Identity還有兩個屬性AuthenticationType(驗證類型)與Name(用戶名稱),你們要注意的是Name屬性,此處的User.Identity.Name將獲得,驗證經過(RedirectFromLoginPage或SetAuthCookie)時,咱們帶入的第一個參數this.Txt_UserName.Text 。這個參數很重要,關係到種種……種種的狀況,何出此言,且聽下回分解……

第二部分 Form 認證的實戰運用

話說上回,簡單地說了一下 Form 表單認證的用法。或許你們以爲太簡單,對那些大內高手來講應該是「灑灑水啦」「小 Kiss 啦(小意思)」。今天我們來點的花樣吧:古有六扇門,拒收葉孤城;東門不颳風,吹雪姓西門;緞帶做憑證,決戰紫禁城。

5、Web.config 的做用範圍

新建項目時, VS.Net 會在項目根目錄創建一個內容固定的 Web.config。除了在項目根目錄,你還能夠在任一目錄下創建 Web.config ,條件就是應用程序級別的節點只能在根目錄的 Web.config 中出現。至於哪些是應用程序級別節點呢,這個問題嘛,其實我也不太清楚,呵呵。電腦不是我發明的,微軟不是我建立的,C# 更不是我說了算的,神仙也有不知道的,因此我不曉得是正常的。話雖如此,只要它不報錯,那就是對的。

關於 Web.config 設置的做用範圍,記住如下兩點:

一、 Web.config 的設置將做用於所在目錄的全部文件及其子目錄下的全部東東(繼承:子隨父姓)

二、 子目錄下的 Web.config 設置將覆蓋由父目錄繼承下來的設置(覆蓋:縣官不如現管)

給你們提個問題:有沒有比根目錄Web.config 的做用範圍還大的配置文件呢?看完第三部分便知分曉。

6、學會拒絕與巧用容許

回到咱們在第一回合新建的測試項目「FormTest」, 既然要進行驗證,按國際慣例,就得有用戶名與密碼。那,這些用戶是管理員本身在數據庫建好呢,仍是用戶註冊、管理員審覈好呢。只要不是通常的笨蛋,都知道選擇後者。大家還別說,我公司還真有個別項目是管理員連到數據庫去建賬號的,屬於比較特殊的笨蛋,我們不學他也罷,仍是老老實實添加兩個頁面吧——註冊頁面(Register.aspx)與審覈頁面(Auditing.aspx)。

問題終於就要浮出水面啦,當你作好Register.aspx時,想訪問它的時候忽然以爲不對勁,怎麼又回到了登陸頁面?你仔細瞧瞧網址,是否是成了:Login.aspx?ReturnUrl=Register.aspx。怎麼辦,用戶就是由於沒有賬號纔去訪問註冊頁面的呀?(這句純屬廢話,有賬號誰還跑去註冊。)我時常對個人同事說:「辦法是人想出來滴!!」

一、新建一個目錄Public,用於存放一些公用的文件,如萬年曆、腳本呀……

二、在「解決方案資源管理器」中右擊點擊目錄Public,新增一個Web.config

三、把上述Web.config的內容通通刪除,僅留如下便可:

<?xmlversion="1.0"encoding="utf-8"?>

<configuration>

<system.web>

<authorization><allow users="*"/></authorization>

</system.web>

</configuration>

終於切入正題了,不容易呀。根據「覆蓋」原則,咱們知道上述Web.config將替代根目錄Web.config中的<authorization>節點設置,即:

<allowusers="*"/>替換<denyusers="?"></deny>

註解:「allow」容許的意思;「*」表示全部用戶;

「deny」拒絕的意思;「?」表示匿名用戶;

所以,處於Public目錄下的文件,容許全部人瀏覽,包括未驗證的用戶。把Register.aspx拖進來吧,不再會有人阻止你瀏覽啦。

除了註冊頁面,咱們還提到一個審覈頁面(Auditing.aspx),審覈權限通常都在管理員或主管手裏,並不想讓其餘人瀏覽此頁面(真理每每掌握在少數人的手裏,這也是無法子的事),怎麼辦?「辦法是人想出來滴」呵呵……新建一個管理員的目錄ManageSys,在此目錄下再新增一個Web.config。內容以下:

<?xmlversion="1.0"encoding="utf-8"?>

<configuration>

<system.web>

<authorization>

<allow users="Admin"/>

<deny users="*"/>

</authorization>

</system.web>

</configuration>

如今的問題就是怎麼才能知道誰是「Admin」呢,這個問題就有點象「個人鞋底有個洞」——天不知地知,你不知我知。閒話少說(要是有稿費多好,我就有多寫幾個字的動力,唉……),你們還記得我在第一部分的結尾嗎?什麼,忘啦!罰你回去看一百遍,記住了再回來。站住,回來!一想到你的記性,我就不放心,第一部分的瀏覽網址是http://blog.csdn.net/cityhunter172/archive/2005/11/06/524043.aspx,回到此處的網址是http://blog.csdn.net/cityhunter172/archive/2005/11/13/528463.aspx

好了,無論那些記很差的傢伙了,大夥繼續往下看。

System.Web.Security.FormsAuthentication.SetAuthCookie(this.Txt_UserName.Text,false);//經過驗證,發放Cookie

以前我曾強調,要注意,第一個參數很重要,重要到什麼程度?說到這,恐怕地球人都知道了——它就是allow與deny的依據。假如此處用戶填寫的是「Admin」即this.Txt_UserName.Text="Admin";那麼進入系統後,他就能訪問ManageSys目錄下的網頁了,其它閒雜人等一概拒之門外。

爲鞏固上述內容,給大夥留個課外做業:此項目有兩部門使用,其中每一個部門分別都有些特定的頁面僅供本部門用戶瀏覽使用,請問該如何使用Web.config達到效果?一樣,答案在第三部分揭曉

7、分散與集中

乍看之下,就象是馬克思列寧主義、***思想、***理論中的辯證關係,大夥放心,偶是學理科的,只明白「高舉程序員的偉大旗幟,以編寫代碼爲中心」。停……

到目前爲此,咱們的測試項目「FormTest」已經擁有兩個目錄三個Web.config,伴隨用戶需求的多樣化,Web.config也會愈來愈多,好比經常使用的文件上傳功能等等。衆多的Web.config分佈在不一樣的目錄裏面,維護起來確定比較煩人。能不能集中起來管理呢,應該咋辦哩?「辦法是……」喲,有人先說出來啦。不錯,「辦法的確是人想出來滴」,我不說,你是否是隻有在一邊涼伴?開玩笑的,爲了讓更多的人記住這句話,我打算告訴你集中管理的辦法。

要想集中管理,不得不用到<location>節點與path屬性。在本項目中,咱們將目錄Public與ManageSys下的設置放在根目錄下的Web.config裏面,以下:

<?xml version="1.0" encoding="utf-8"?>

<configuration>

<location path="Public">

<system.web>

<authorization>

<allow users="*"/>

</authorization>

</system.web>

</location>

<location path="ManageSys">

<system.web>

<authorization>

<allow users="Admin"/>

<deny users="*"/>

</authorization>

</system.web>

</location>

<system.web>

<!--這裏放置原來根目錄Web.config的內容,就不列出來了-->

</system.web>

</configuration>

須要提醒的是

一、<location>節點的位置是在<configuration>的一個子節點,它與原有的<system.web>屬於並列關係

二、<location>節點只須要放入對應子目錄Web.config中的<system.web>的節點內容

8、額外的保護

第二部分就要結束了,如今時間已經是凌晨4點50分,我容易嘛我。認證的目的就是爲了防止他人非法瀏覽頁面,或未經許可以使用某些功能。固然,世上沒有絕對的安全,現在MD5加密都被咱們國人給破解了,就是最好的例證。

細心的人可能早就發現ASP.NET的安全認證只針對.aspx、.ascx……等ASP.NET文件起做用,而對普通頁面與文件卻「視而不見」,如.htm、.js、.jpg等。經過如下步驟你就能夠保護你想保護的文件類型。

一、打開Internet信息服務(IIS)管理器→右擊本項目虛擬→屬性,以下圖

(http://blog.csdn.net/images/blog_csdn_net/cityhunter172/85935/r_aspxForm01.JPG)

二、點擊按鈕「配置」,出現以下對話框:

(http://blog.csdn.net/images/blog_csdn_net/cityhunter172/85935/r_aspxForm02.JPG)

三、雙擊.aspx的應用程序擴展→查看對話框內容,以下圖:

(http://blog.csdn.net/images/blog_csdn_net/cityhunter172/85935/r_aspxForm03.JPG)

四、複製「可執行文件」的全路徑名稱後→點擊「取消」返回上一層對話框→點擊按鈕「添加」

五、粘貼剛纔複製的內容(個人系統裝在D盤,因此內容爲D:"WINDOWS"Microsoft.NET"Framework"v1.1.4322"aspnet_isapi.dll)→填寫後綴名爲.htm→填寫動做限制爲「GET,HEAD,POST,DEBUG」(爲方便省事你可選所有)

六、最後點擊「肯定」→往項目中添加HtmlPage1.htm→在IE瀏覽器的地址欄直接輸入http://localhost/FormTest/HtmlPage1.htm→觀看測試效果

最後送你們一段Web.config設置,發完睡覺,實在是困的不行了。

<location path="決戰紫禁城">

<system.web>

<authorization>

<allow users="葉孤城"/>

<allow users="西門吹雪"/>

<deny users="*"/>

</authorization>

</system.web>

</location>

<location path="金鑾殿屋脊">

<system.web>

<authorization>

<allow users="腰繫緞帶之人"/>

<deny users="*"/>

</authorization>

</system.web>

</location>

第三部分實現單點登陸(SingleSignOn)

「等了很久終於等到今天,寫了很久終於就快完結,可是網友的反應卻讓我有一些的傷心。盼了很久終於盼到今天,忍了很久終於把此文撰寫,那些受冷落的無奈早就無所謂,累也不說累」(歌詞《今天》新演繹)。看着人家的Blog文章的評論是一條接一條,再瞧瞧本身:「無人問津吶,真…無…奈……唉,沒人理我,仍是回家吧。」「哎,還沒開始寫,怎麼就走了?回去幹什麼呢?」回去寫做業去啊,上回交待的課外做業你作了沒?(注:http://blog.csdn.net/cityhunter172/archive/2005/11/13/528463.aspx在第二部分第六節佈置的課外做業:此項目有兩部門使用,其中每一個部門分別都有些特定的頁面僅供本部門用戶瀏覽使用,請問該如何使用Web.config達到效果?)

不知有多少人作了做業,其實答案並不難。只須要在驗證用戶名與密碼後,取得該用戶的部門名稱或部門代碼,把它做爲判斷的依據就好了。最好不要用部門的數字ID,那樣不利於之後的維護。

有一個祕密,通常人我不告訴他。Web.config中的<location>節點的path屬性能夠是一張具體頁面的相對URL路徑,以下:<location path="ManageSys/Auditing.aspx">

好了,接下來就要揭開「比根目錄Web.config的做用範圍還大的配置文件」之謎啦,它就是藏匿在Windows系統目錄下,支配整個.NetFramework配置的傳說中的Machine.config!!下面請你們以熱烈的掌聲,歡迎咱們這位神祕俠客的閃亮登場……

9、Machine.config

Machine.config,性別不詳,年齡未知,家庭出身:XML。深藏於「雲深不知處」的操做系統目錄下的某某地方(注:C:"WINDOWS【或WINNT】"Microsoft.NET"Framework"v1.1.4322【或v1.0.3705】"CONFIG),控制着「更上一層樓」的.NETFramework的本機配置。接下來簡要的講解一下它的內容,以及它與Web.config的關係。

通過「松下問童子」,咱們好不容易找到這位隱者,打開一看,乖乖,足有3700多行!!「叫我怎麼能不難過,偶只想看看是啥結構,可內容實在是太多太繁瑣……」還記得偶常常對同事說的一句話麼:「辦法是人想出來的!」它不是有三千七百多行嗎,那咱們就無論三七可否得出二十一啦,把它拷出來先。它不是XML出身嗎,那我們就還其正身,從新命名爲「machine.xml」。接着用IE瀏覽器將這位改頭換面的隱者打開,把節點與註釋一一合攏。這回你看到了吧,是否是頗有成就感?你要是想謝謝我,就讓我看到你在此文下面的評論吧。多多益善,呵呵。

Machine.config與Web.config是啥關係?四個字——父子關係。記得我在第二部分第五節講解Web.config做用範圍的時提到兩點——繼承與覆蓋(詳見http://blog.csdn.net/cityhunter172/archive/2005/11/13/528463.aspx),在此也一樣適用。

一、Machine.config中的設置將做用於運行在本機的全部站點及其虛擬目錄,遇到子目錄將一直繼承下去。

二、Web.config中的設置將覆蓋由Machine.config中繼承下來的對應的節點設置

說到這,再告訴你們一個祕密——「世上本無祕密,知道的人多了,便成了不是祕密的祕密!」

a、Machine.config中的<system.web>節點全部內容都能出如今項目根目錄下的Web.config中,也就是說能在Web.config中的內容已經在Machine.config中一一列出;

b、其中<system.web>節點下的<pages>還能出如今頁面上,如:HTML視圖下,在WebForm1.aspx的第一行加上<pages>的節點內容validateRequest="false"(此句意思是不對WebForm1.aspx頁面文本框輸入的值,是否包含「<」「>」等等具備危險性的代碼進行檢查,下一節將具體運用到)

<%@ Page language="c#" Codebehind="WebForm1.aspx.cs" AutoEventWireup="false" Inherits="FromTest.WebForm1" validateRequest="false"%>

10、單點登陸(SingleSignOn)的前提條件

以前說了這麼多關於Machine.config的事,都是爲了實現單點登陸做鋪墊,那何爲單點登陸(SingleSignOn)?從字面理解就是在一個地方登陸,一般運用於ASP.NET分佈式環境中(跨單個服務器上的多個應用程序或在網絡場中)的Forms身份驗證。打個比方,就比如如今Sohu(搜狐)與Chinren(中國校友錄)的作法,我在Sohu登陸之後就不須要在Chinaren登陸了。臺灣與香港又把SingleSignOn稱之爲「單一登入」。

要想實現此功能,首要條件是須要一組用於加密與驗證加密的密鑰。它們位於Machine.config中,修改<system.web>節點下的<machineKey>節點屬性,以下:

<machineKey

firstKey="172"

copyrightKey="Cityhunter172"

validationKey="AD117F2F286CDCB15A9D1D4535E16DB0248026939**AUTHOR**CITYHUNTER172****WEBSITE**172*MEIBU*COM****MAILTO**CITYHUNTER172@126*COM*****F2F286CDCB15A9D1D4535E16DB0248026939"

secondKey="meibu"

decryptionKey="3C89AE62AD117F2F286CDCB15A9D1D4535E16DB0248026939" validation="SHA1"

thirdKey="com"

/>

一、validationKey爲用於驗證加密數據的密鑰。最小長度爲40個字符(20字節),最大長度爲128個字符(64字節)。

二、decryptionKey爲用於加密數據的密鑰。長度只有16個字符(8字節)與48個字符(24字節)兩種。

三、validation爲用數據驗證使用的加密類型。擁有「SHA1」「MD5」「3DES」三種方法

四、大夥參照上述<machineKey>試着在WebForm1.aspx運行下列語句:

this.TextBox2.Text="ht"+"tp"+"://"+firstKey+"."+secondKey+"."+thirdKey

你們在修改以前請先備份一下Machine.config,到時要是出錯可別怪我沒提醒你。以上密鑰並非胡亂得來的,接下來向你們介紹生成密鑰的方法。

咱們把上一節中提到的WebForm1.aspx拖入本項目的Public目錄下,再往頁面上拖入一個TextMode=MultiLine的TextBox3與一個Button編寫按鈕事件與函數:

privatevoidButton1_Click(objectsender,System.EventArgse)

{

stringdecStr=this.CreateKeyString(int.Parse(this.TextBox1.Text));

stringvalStr=this.CreateKeyString(int.Parse(this.TextBox2.Text));

this.TextBox3.Text=string.Format("<machineKeyvalidationKey=""{0}""decryptionKey=""{1}""validation=""SHA1""/>",valStr,decStr);

}

///<summary>

///生成加密型強隨機Key值

///</summary>

///<paramname="i">Key的有效長度:

///decryptionKey的有效值爲8或24;

///validationKay的有效值爲20至64

///</param>

privatestringCreateKeyString(inti)

{

System.Security.Cryptography.RNGCryptoServiceProvider rng=newSystem.Security.Cryptography.RNGCryptoServiceProvider();//加密隨機數生成器

byte[]bt=new byte[i];

rng.GetBytes(bt);//用加密型強隨機值序列填充字節數組

System.Text.StringBuilder str=newSystem.Text.StringBuilder();

for(intj=0;j<i;j++)

{

str.Append(string.Format("{0:X2}",bt[j]));//轉換成大寫的十六進制文本

}

returnstr.ToString();

}

每次點擊按鈕生成密鑰都不一樣,你們不妨多點幾回。切換至HTML視圖,到WebForm1.aspx第一行把validateRequest="false"去掉,而後再多點幾回Button1試試,看看會有什麼效果,嘿嘿………

11、單點登陸(SingleSignOn)的站點示例

將上述TextBox3產生的文本,覆蓋Machine.config中的,如今你的機器已經具有了單點登陸的條件。大夥能夠再新建一個項目FormTest2,從FormTest2登陸後直接輸入FormTest中的Default.aspx的網址(http://localhost/FormTest/Default.aspx),反之亦可。

下面結合實例講解:偶在山東每步科技網站申請了一個免費二級域名172.meibu.com,並下載了每步的4.0版的動態域名解析客戶端。如今使用ADSL拔號上網,也就是說個人電腦已經成了Web服務器,同時支持SQLServer、Oracle空間高達200G想怎麼弄就怎麼弄,夠牛吧,嘿嘿。佈署上來的項目有環勝數碼網站、權限管理系統、IT內部管理網,以上三個項目是偶一人全權開發的。所謂全權就是從數據庫存儲過程寫到.cs代碼再到javascript,最後到美工都是偶一手搞定的。^_^我把這三個不相干的項目作成了單點登陸的模式,加上整合站點的主頁面,共有四個地方能夠進行登陸。由於用戶Table的結構不一樣,所以只有一個入口能在進入後,在跳轉站點時不會出錯,那就是在整合頁面登陸。

如今我想把環勝數碼這個站點單獨脫離出來,而剩下的兩個站點繼續實現單點登陸,該怎麼作呢?或者是個人ASP.NET的空間是租的,服務商確定不可能讓我修改Machine.config,我又咋辦哩?「辦法是人想出來滴!!」,根據上述Machine.config與Web.config的關係,咱們能夠把<machineKey>節點放入項目根目錄下Web.config的<system.web>節點。以下:

一、權限管理系統項目的Web.config用於Form認證的設置

<machineKeyvalidationKey="AD117F2F286CDCB15A9D1D4535E16DB0248026939**AUTHOR**CITYHUNTER172****WEBSITE**172*MEIBU*COM****MAILTO**CITYHUNTER172@126*COM*****F2F286CDCB15A9D1D4535E16DB0248026939"decryptionKey="3C89AE62AD117F2F286CDCB15A9D1D4535E16DB0248026939"validation="SHA1"/>

<authenticationmode="Forms">

<formsloginUrl="Login.aspx"name="172.MEIBU.COM_WARRANT"></forms>

</authentication>

<authorization><denyusers="?"></deny></authorization>

二、IT內部管理網項目的Web.config用於Form認證的設置

<machineKeyvalidationKey="AD117F2F286CDCB15A9D1D4535E16DB0248026939**AUTHOR**CITYHUNTER172****WEBSITE**172*MEIBU*COM****MAILTO**CITYHUNTER172@126*COM*****F2F286CDCB15A9D1D4535E16DB0248026939"decryptionKey="3C89AE62AD117F2F286CDCB15A9D1D4535E16DB0248026939"validation="SHA1"/>

<authenticationmode="Forms">

<formsloginUrl="Login.aspx"name="172.MEIBU.COM_IT"></forms>

</authentication>

<authorization><denyusers="?"></deny></authorization>

你們可能會迫不急待的去試一把,偶同意這樣的作法,由於事實是檢驗真理的惟一辦法。你不去試着本身動手,光看我在這說是很難提升的。先別急,我已經知道你想說什麼,聽聽我慢慢向你解釋:

a)兩個項目Web.cinfig的<machineKey>節點確保如下幾個字段徹底同樣:validationKey、decryptionKey、validation

b)兩個項目的Cookie名稱必須相同,也就是<forms>中的name屬性,這裏咱們把它統一爲name="172.MEIBU.COM_PROJECT"

c)注意區分大小寫

在整合的過程當中,我把遇到的問題向大夥說一下,以避免大家走一樣的路。

1)首先應該是用戶管理的問題,把兩個項目的用戶整合在一塊兒,可不是一件容易的事,原則是新建一個新的Table只存放賬號與密碼,用帳號作關聯,編寫觸發器,作到Table之間的同步;

2)不要期望兩個項目間用Session進行傳值,兩個應用程序的Session是沒法共享的。網上有人曾把類庫(編譯後的.dll文檔)放入同一個bin文件夾實現過Session共享,這樣的作法其實是把兩個項目變相合併成一個應用程序,不是咱們所想要的,理由很簡單:Sohu與Chinaren的服務器分處兩地該怎麼辦?

3)項目間的傳值,可用Cookie實現。在第一部分的第三節(http://blog.csdn.net/cityhunter172/archive/2005/11/06/524043.aspx)咱們介紹了只要運行System.Web.Security.FormsAuthentication.SetAuthCookie方法便可實現登陸,單點登陸的實質就是含有身份驗證票的Cookie能在項目間共用。

接下來,有必要向你們介紹一下Cookie在.Net中的用法。

12、Cookie在ASP.NET中的用法

你們也許和我同樣,不多在ASP.NET中使用Cookie,傳參數呀,存變量呀,用的比較多的是Session或ViewState以及隱藏控件,有的乾脆用「?」的請求方式。

一、Cookie存放的目錄

Cookie是存放在客戶端的東東,放在「TemporaryInternetFiles」目錄,因此說存在安全性的問題。大夥可經過如下方式找到具體位置:打開控制面板→Internet選項→常規→Internet臨時文件→設置→便可看到「當前位置」,→點擊「查看文件」將直接打開該文件夾,你也能夠點擊「移動文件夾」變動它所在的位置。參照下圖(http://blog.csdn.net/images/blog_csdn_net/cityhunter172/85935/r_aspxForm04.jpg與http://blog.csdn.net/images/blog_csdn_net/cityhunter172/85935/r_aspxForm05.jpg)

二、Cookie的有效期

從上圖咱們能夠清楚的看到每一個Cookie文檔的「截止期」(即爲有效期)。在有效期內,當登陸計算機的用戶Administrator再次訪問172.meibu.com時,那麼IE就會在請求頁面的同時,連同上述的名稱爲「Cookie:administrator@172.meibu.com」的Cookie文檔內容一塊兒發送給服務器。

若該文檔包含多個Cookie的值時,截止期則以最後的失效期爲準。

三、Cookie的類型

這裏咱們按有效期來分,分爲兩種:

a)即時型

指的是關閉瀏覽器(全部瀏覽172.meibu.com的IE)後,Cookie便失效,此類Cookie不會在「TemporaryInternetFiles」目錄出現。其實它也有截止期的,爲「0001-01-01」

b)持久型

就是已指定具體「截止期」的,可以在「TemporaryInternetFiles」目錄裏面找到的Cookie

四、Cookie的內容

雙擊打開「Cookie:administrator@172.meibu.com」,咱們看到如下內容,以下圖(http://blog.csdn.net/images/blog_csdn_net/cityhunter172/85935/r_aspxForm06.jpg):

上圖中,「■」是換行符,你如果要打破什麼鍋來問我究竟是怎麼知道的話。我卻是會很樂意的告訴你:這就是經驗!偶從學習C#那刻起,就拿第一個Windows程序——記事原本開刀,保存文檔時得來的經驗。

因此服務器讀出來的格式以下圖(http://blog.csdn.net/images/blog_csdn_net/cityhunter172/85935/r_aspxForm07.jpg):

五、在ASP.NET頁面發放Cookie

發送上述Cookie的.cs代碼爲:

System.Web.HttpCookie ck=new HttpCookie("ckValue0");

ck["Author"]="CityHunter";

ck.Expires=System.DateTime.Now.AddMinutes(10);//若不指定,則爲即時型Cookie

//ck.Path="/FormTest/ManageSys";//設置Cookie的虛擬路徑,注意必定要以「/」開頭,不然爲無效Cookie;請你們自行看一下它與在客房端的Cookie文檔「名稱」與「Internet地址」的關係

Response.Cookies.Add(ck);

ck=newHttpCookie("ckValue1");//從新新建一個名爲ckValue1的Cookie

ck.Expires=System.DateTime.Now.AddMinutes(20);//即刻起20分鐘後失效

ck["E_Mail"]="cityhunter172@126.com";//設置ckValue1中的E_Mail值

ck["PersonalWeb"]="172.meibu.com";

Response.Cookies.Add(ck);//添加此Cookie

六、取回已發放Cookie的值

Response.Write(Request.Cookies["ckValue0"]["Author"]+"<br>");//用不着說明了吧

Response.Write(Request.Cookies["ckValue1"]["E_Mail"]+"<br>");

Response.Write(Request.Cookies["ckValue1"]["PersonalWeb"]);

很久沒有出做業啦(何出此言?),這第三篇呀,但是花了偶兩個星期的業餘時間調試、總結、撰寫哪,都說時光貴如金,不知我花的這些時間能換來多少銀子?換銀子,我看是沒期望啦,能獲得閣下的一句評論,偶也知足了。記住,你的評論就是偶繼續寫下去的動力。

做業:給Cookie賦於如下值,怎樣獲得它的正確值

ck["str1"]="2222";

ck["str"]="str0=11111&str1=223";

能夠確定的是Request.Cookies["ckValue1"]["str"]得不到「str0=11111&str1=223」這個字串,你們不妨試一下Request.Cookies["ckValue1"]["str1"]會獲得意想不到的字串喲。

提示:使用Server.UrlEncode()與Server.UrlDecode()

十3、發放永久性的驗證Cookie

終於……終於……最後一個章節,驀然回首,洋洋灑灑十二章。沒想到年少時寫不完做文的偶,竟然也能編出幾千餘字的文章來呀,不得不佩服偶本身呀!再回首,一大片暈倒的人……。永遠到底有多遠?永久到底是多久?只有天知道。

你們登陸CSDN的時候是否留意到一個「2周內不用再登陸」的複選框,它又是怎麼作到的呢?你們是否曾遇到過這樣的困惑:在執行System.Web.Security.FormsAuthentication.SetAuthCookie時明明已指定createPersistentCookie爲true爲什麼關閉瀏覽器仍不能直接訪問網站?下面咱們就這個問題給你們解釋一下,且介紹如何手工建立身份驗證票並加入Cookie中。

System.Web.Security.FormsAuthenticationTicket tk=newSystem.Web.Security.FormsAuthenticationTicket(

1,//指定版本號:可隨意指定

"Admin",//登陸用戶名:對應Web.config中<allowusers="Admin"…/>的users屬性

System.DateTime.Now,//發佈時間

System.DateTime.Now.AddYears(100),//失效時間:100年之後,夠永夠久了吧

false,//是否爲持久Cookie:還沒有發現有何用,至少目前偶還不知,下面會有說明

"測試用戶數據"//用戶數據:可用((System.Web.Security.FormsIdentity)User.Identity).Ticket.UserData獲取

);

stringstr=System.Web.Security.FormsAuthentication.Encrypt(tk);//加密身份驗票

//聲明一個Cookie,名稱爲Web.config中<formsname=".APSX"…/>的name屬性,對應的值爲身份驗票加密後的字串

System.Web.HttpCookieck=newHttpCookie(System.Web.Security.FormsAuthentication.FormsCookieName,str);

//指定Cookie爲Web.config中<formspath="/"…/>path屬性,不指定則默認爲「/」

ck.Path=System.Web.Security.FormsAuthentication.FormsCookiePath;

//此句很是重要,少了的話,就算此Cookie在身份驗票中指定爲持久性Cookie,也只是即時型的Cookie關閉瀏覽器後就失效;所以上面我說:我是真的還不知在身份驗票中指定爲持久性Cookie有何用。

ck.Expires=System.DateTime.Now.AddYears(100);

Response.Cookies.Add(ck);//添加至客房端

後記

此係列文章共三部分,歷時一個月完成(2005-11-05~2005-12-06)。以上是我學習並用於實踐的一些經驗,在此拿出來與你們一塊兒分享。代碼都是通過調試的,若有任何疑問,可在CSDN論壇(http://community.csdn.net/)找到我,個人ID是cityhunter172(可用此ID發短消息給我),暱稱爲寒羽楓,歡迎你們批評指正。

第四部分Form認證的補充

前三篇在CSDN論壇公佈後,效果如同「神仙放屁——果真不一樣凡(反)響」。爲感謝廣大網友的熱情與支持,這不,通過這一陣子的醞釀、修煉,特地準備了這第四響。

以前咱們講述的使用Form認證明現單點登陸,正如網友所說的那樣,只能在同一域名下使用。對於跨域名的單點登陸,除了使用Passport認證外,咱們仍是能夠用Form認證的,只是要講究方法而已啦。正所謂「山不轉水轉,人不轉心轉」。

1、跨域名的解決思路

在MSDN2003上搜索關鍵字「Passport」,偶找到一篇「Passport身份驗證提供程序」。文章講述了Passport的認證原理,共8條,我就很少說了,大夥自個看吧。其中有一句話,引發偶的注意:「……響應在查詢字符串中包含一個加密的Passport Cookie……」。也正是此句纔有了下面的思路。

所謂認證的經過與否,其實質就是檢測有無發放有效的Cookie,使用Form也好,運用Passport也罷,都是Cookie在起做用。也就是說,咱們只要把有效的Cookie在登陸後一次性發放給客戶端就得了。

2、跨域名、跨服務器的單點登陸方法

一、如何在本機模擬跨域名、跨服務器的SingleSignOn

只要瀏覽網址不一樣就至關於不一樣域名,在本機至少有如下三種。它們雖然是同一項目,彼此卻不能共用Session與Cookie,也就沒法共享身份驗證票:

a).http://localhost/FormTest/Login.aspx

b).http://127.0.0.1/FormTest/Login.aspx

c).http://My_Computer_Name/FormTest/Login.aspx//以電腦名稱瀏覽站點

d).http://192.168.0.8/FormTest/Login.aspx//以網卡地址瀏覽站點

e).http://172.meibu.com/FormTest/Login.aspx//擁有國際域名

二、在ASP.NET中如何提交給其它頁面

用過ViewState的大概都知道,ViewState是保存在客戶端的。不知大夥注意沒有,ASP.NET爲每張.aspx頁面都配備了獨自的ViewState,且被解析後都是以一個name="__VIEWSTATE"的隱藏控件值來保存ViewState。每次頁面提交,服務器都會檢查該控件的值有無被篡改,如此一來就註定.aspx只能提交給本頁。服務器是死的,人是活的,咱們不能被這些條條框框限定死了,咱們要把程序寫成活的。

下面我們從http://localhost/FormTest/Login.aspx輸入用戶名與密碼,而後提交給http://127.0.0.1/FormTest/Public/LoginTransfer.aspx。Login.aspx與LoginTransfer.aspx都包含用戶名輸入框一個、密碼輸入框一個、登陸按鈕一個。在Login.aspx頁面加入如下代碼:

this.Btn_Login.Attributes["onclick"]="SingleSignOn()";//指定執行腳本事件

在Login.aspx頁面上插入如下腳本:

<script language="javascript">

Function SingleSignOn()

{

//只能用腳本改變指定Form提交的對象

document.getElementById("Form1").action="http://127.0.0.1/FormTest/Public/LoginTransfer.aspx?FromUrl="+window.location.href;

//把隱藏控件__VIEWSTATE中的值變動爲LoginTransfer.aspx解析後出現的值,以實際看到的值爲準

document.all.__VIEWSTATE.value="dDwtMTkyODUzMTMyNzs7Pv1cp2RaxUcr5hGYf8ILX9/EMKy8";

}

</script>

注意事項

a).LoginTransfer.aspx出現的控件及其ID,必須可以在Login.aspx找到

b).控件的ID必須一致,且能一一對應

c).關於__VIEWSTATE中的值,它與頁面控件ID無關,與瀏覽該頁面的網址無關,目前我只知道和控件的數量、類型、名字空間(namespaceFormTest.Public)以及存在的ViewState有關係。你們在測試時,以直接瀏覽http://127.0.0.1/FormTest/Public/LoginTransfer.aspx後,查看頁面源文件所看到的值爲準。

d).提交後,將觸發並執行LoginTransfer.aspx中的Btn_Login_Click事件

三、基本思路

各個站點的登陸頁面統一將用戶名與密碼提交給LoginTransfer.aspx,同時各個站點須要一個增長Cookie的頁面,用於將加密後的身份驗證Cookie添加至客戶端。此乃通過一番考量後,最終肯定的可行性方案。

四、第一種思路——天女散花

何謂天女散花,就是把Cookie在登陸後一次性全發放出去,就如同天仙在空中散花同樣,場面是何等的壯觀。下面開始寫代碼:

爲更好的區分,咱們將負責添加Cookie的頁面分開命名:

a).http://localhost/FormTest/Public/AddCookie_A.aspx

b).http://127.0.0.1/FormTest/Public/AddCookie_B.aspx

c).http://My_Computer_Name/FormTest/Public/AddCookie_C.aspx

這三張頁面的功能同樣,因此代碼也就相同囉

privatevoidPage_Load(objectsender,System.EventArgse)

{

stringfrom=Request["FromUrl"];//起始URL路徑

stringnext=Request["NextUrl"];//還須要跳轉的URL

stringkey=Request["CookieTicket"];//已加密的Cookie文本

if(key!=null&&key!="")

{

System.Web.HttpCookieck=newHttpCookie(System.Web.Security.FormsAuthentication.FormsCookieName,key);

ck.Path=System.Web.Security.FormsAuthentication.FormsCookiePath;

ck.Expires=System.DateTime.Now.AddYears(100);

Response.Cookies.Add(ck);//將傳過來的已加密的身份驗證票添加至客房端

stringurl=next.Split(';')[0];//從URL中拆分出將要跳轉的下一張頁面

next=next.Replace(url+";","");//帶入下一輪跳轉的字串

if(url!="")

{

//跳至下一頁面Response.Redirect(url+"?CookieTicket="+key+"&FromUrl="+from+"&NextUrl="+next);

}

else//已沒有下一頁面可供跳轉

{

Response.Redirect(from);//回到起始頁面

}

}

}

接下來編寫LoginTransfer.aspx的代碼:

//頁面常量allLoginUrl存放全部站點的AddCookie.aspx的URL,注意以;分隔

publicconststringallLoginUrl=

"http://localhost/FormTest/Public/AddCookie_A.aspx;"

+"http://127.0.0.1/FormTest/Public/AddCookie_B.aspx;"

+"http://My_Computer_Name/FormTest/Public/AddCookie_C.aspx;";

偶已在上面講述了,如何點擊Login.aspx中的登陸按鈕Btn_Login將用戶名與密碼提交給LoginTransfer.aspx,並執行LoginTransfer.aspx中的Btn_Login_Click事件。

privatevoidBtn_Login_Click(objectsender,System.EventArgse)

{

stringfrom=Request["FromUrl"];//起始URL路徑

stringnext=this.allLoginUrl;

//因爲控件ID相同,因此此處獲得的是由Login.aspx提交過來的用戶名與密碼

if(this.Txt_LoginName.Text=="Admin"&&this.Txt_Password.Text=="123456")

{

System.Web.Security.FormsAuthenticationTickettk=newSystem.Web.Security.FormsAuthenticationTicket(1,"Admin",System.DateTime.Now,System.DateTime.Now.AddYears(100),false,"測試用戶數據");

stringkey=System.Web.Security.FormsAuthentication.Encrypt(tk);//獲得加密後的身份驗證票字串

stringurl=next.Split(';')[0];//從URL中拆分出將要跳轉的下一張頁面

next=next.Replace(url+";","");//帶入下一輪跳轉的字串

Response.Redirect(url+"?CookieTicket="+key+"&FromUrl="+from+"&NextUrl="+next);//跳至下一頁面

}

}

五、第二種思路——后羿射日

后羿射日,意思指的是用戶點哪就跳哪。他如果點「火坑」,你也得往裏跳,由於用戶是上帝嘛。咱們增長一個通行證頁面MyPassport.aspx,由http://127.0.0.1/FormTest/Public/LoginTransfer.aspx發放驗證Cookie後直接跳轉至http://127.0.0.1/FormTest/MyPassport.aspx。不要告訴我你不會,你要是真不會,那偶也無法子啦,還得請你回頭看看,偶在第三篇是如何講述發放永久性驗證Cookie吧(http://blog.csdn.net/cityhunter172/archive/2005/12/06/545301.aspx)。還須要一張用做跳板的跳轉頁面MyTransfer.aspx。

MyPassport.aspx的代碼:

<atarget="_blank"

href="MyTransfer.aspx?goto=http://localhost/FormTest/Public/AddCookie_D.aspx">

美麗的天使</a>

<atarget="_blank"

href="MyTransfer.aspx?goto=http://127.0.0.1/FormTest/Public/AddCookie_E.aspx">

快樂的天堂</a>

<atarget="_blank"

href="MyTransfer.aspx?goto=http://My_Computer_Name/FormTest/Public/AddCookie_F.aspx">

大大的火坑</a>

MyTransfer.aspx的代碼:

privatevoidPage_Load(objectsender,System.EventArgse)

{

//獲取身份驗證票

System.Web.Security.FormsAuthenticationTickettk=((System.Web.Security.FormsIdentity)User.Identity).Ticket;

stringkey=System.Web.Security.FormsAuthentication.Encrypt(tk);//每次加密後的字串都是不一樣的

stringnext=Request["goto"];//將要跳轉的URL

Response.Redirect(url+"?CookieTicket="+key);//跳轉至下一頁面

}

AddCookie_D.aspx、AddCookie_E.aspx、AddCookie_F.aspx這三張頁面的代碼:

stringkey=Request["CookieTicket"];//已加密的Cookie文本

if(key!=null&&key!="")

{

System.Web.HttpCookieck=newHttpCookie(System.Web.Security.FormsAuthentication.FormsCookieName,key);

ck.Path=System.Web.Security.FormsAuthentication.FormsCookiePath;

ck.Expires=System.DateTime.Now.AddYears(100);

Response.Cookies.Add(ck);//將傳過來的已加密的身份驗證票添加至客房端

Response.Redirect("../Index.aspx");//跳轉至你真正想帶客戶去的地方

}

六、點評

二者共同點:

a).每一個站點都須要一個登陸的提交點、一張添加Cookie的頁面。

b).由於只能靠發放驗證Cookie來識別身份,因此一臺電腦不能同時登陸兩個賬號。

c).都存在不一樣程度的安全隱患。

二者不一樣點:(天女散花如下簡稱「開女」,后羿射日就簡稱「后羿」)

a).天女一次性發放Cookie,若是站點較多,處理起來仍是須要一些時間的。然後羿則相反,站點再多也不怕。

b).天女在散花的過程當中,若是中途被卡住,則須要一個錯誤處理機制作回退處理。后羿則不須要。

c).天女在登陸後能夠直接在IE地址瀏覽其想看的站點;然後羿則必須從通行證的跳板頁面進入才行。

根據上述問題,給幾點建議:

a).不要使用永久性Cookie,應指明身份驗證票的過時時間,注意不是Cookie的有效期。

b).在身份驗證票的UserData中加入其它的驗證信息或存放用戶ID

c).在網絡通暢的狀況下,好比局域網,站點又相對較少,建議選用天女。50個站點之間作跳轉應該不會超過10秒(前提是已編譯好了,且不是初次訪問)。

3、跨域名、跨服務器的退出方法

只要理解了「天女散花」,退出就比較容易啦。爲每一個站點準備一個用於退出的頁面,以下:

a).http://localhost/FormTest/Public/Logout.aspx

b).http://127.0.0.1/FormTest/Public/Logout.aspx

c).http://My_Computer_Name/Public/FormTest/Logout.aspx

privatevoidPage_Load(objectsender,System.EventArgse)

{

System.Web.Security.FormsAuthentication.SignOut();//刪除Cookie中的身份驗證票

stringfrom=Request["FromUrl"];

stringnext=Request["NextUrl"];

stringurl=next.Split(';')[0];

next=next.Replace(url+";","");

if(url!="")

{

Response.Redirect(url+"?FromUrl="+from+"&NextUrl="+next);

}

else

{

Response.Redirect(from);

}

}

對啦,還有一張LogoutTransfer.aspx.,代碼偶就不寫,你們自個完成吧。

相關文章
相關標籤/搜索