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.,代碼偶就不寫,你們自個完成吧。