ASP.NET2.0中的單點(diǎn)登錄簡(jiǎn)介及實(shí)現(xiàn)
在這篇文章中,Masoud討論了應(yīng)用asp.net中統(tǒng)一身份驗(yàn)證模型進(jìn)行跨應(yīng)用程序驗(yàn)證的問題,包括:Membership Providers, web.config配置,配置文件的加密解密等。在文章的最后,作者提供了通過asp.net login controls來驗(yàn)證的程序。
by Masoud Tabatabaei:
通常在你要實(shí)現(xiàn)asp.net web應(yīng)用程序的身份驗(yàn)證時(shí),你需要為你的每一個(gè)應(yīng)用程序創(chuàng)建一個(gè)登錄頁(yè)面。想象一下,如果你有兩個(gè)或者更多的互相關(guān)聯(lián)的web應(yīng)用程序,你可能希望通過某種機(jī)制為你的所有帶關(guān)聯(lián)的應(yīng)用程序?qū)崿F(xiàn)僅出現(xiàn)一次登錄頁(yè)面。這樣,一旦你登錄了一次,你就可以瀏覽所有的關(guān)聯(lián)程序,而不再需要額外的登錄了。單點(diǎn)登錄(SSO)就是這樣的訪問控制機(jī)制,它允許一個(gè)用戶通過一次驗(yàn)證就可以訪問所有軟件系統(tǒng)資源。
試想你在你的服務(wù)器上創(chuàng)建了兩個(gè)或者更多的web站點(diǎn)。就像其他的web站點(diǎn)一樣,你只是使用asp.net權(quán)限驗(yàn)證機(jī)制來驗(yàn)證你的用戶。那么,你的這些站點(diǎn)可能需要一個(gè)或更多的登錄頁(yè)面?,F(xiàn)在你正試圖證明怎么樣通過更改你的配置來實(shí)現(xiàn)跨程序登錄。換句話說,我們只想給我們的程序配置一個(gè)登錄頁(yè)面,并且一旦用戶通過了驗(yàn)證,他就可以瀏覽其他所有的站點(diǎn),而不需要另外的登錄。在這篇文章的附錄中,你也可以看到如何加密你的配置文件。
ASP.NET2.0中的單點(diǎn)登錄簡(jiǎn)介:什么是單點(diǎn)登錄?它是怎樣工作的?
在許多的公司里,他們有一些以web站點(diǎn)或web應(yīng)用程序?yàn)楸憩F(xiàn)層的系統(tǒng)。自然,由于安全議題他們將需要通過基于asp.net 2.0,通過Membership Provider 和 Role Provider 或者定制實(shí)現(xiàn)權(quán)限驗(yàn)證和權(quán)限驗(yàn)證系統(tǒng)。不論怎樣,所有的站點(diǎn)都會(huì)默認(rèn)有一個(gè)確定用戶的ID和密碼在數(shù)據(jù)庫(kù)中是否有效的”login.aspx” web窗體.當(dāng)你只有一個(gè)站點(diǎn)或者這些站點(diǎn)都是獨(dú)立運(yùn)行時(shí),這樣做是沒有問題的。但是當(dāng)你有兩個(gè)或多個(gè)站點(diǎn),而且站點(diǎn)間是關(guān)聯(lián)在一起或鏈接在一起的,你沒準(zhǔn)就會(huì)問:為什么每個(gè)應(yīng)用程序你都必須登錄一次?為什么你不可以只有一個(gè)”login.aspx”來實(shí)現(xiàn)驗(yàn)證,并讓所有不關(guān)聯(lián)程序真正統(tǒng)一起來。幸運(yùn)的是,在asp.net 2.0中你可以通過同樣的配置來實(shí)現(xiàn)跨應(yīng)用程序訪問,不論是你的新的站點(diǎn)還是已經(jīng)存在的站點(diǎn)。
在asp.net配置文件(web.config)中有一個(gè)配置節(jié)(在< system.web中)命名為< machineKey>,負(fù)責(zé)加密和解密窗體(這些窗體可以讀窗體權(quán)限驗(yàn)證cookies)權(quán)限認(rèn)證的cookie數(shù)據(jù)和view-state數(shù)據(jù),也負(fù)責(zé)校驗(yàn)進(jìn)程外(out-of-process)session 狀態(tài)標(biāo)識(shí)。所以當(dāng)用戶一旦被驗(yàn)證通過并且有一個(gè)cookie保存到了本地計(jì)算機(jī),其他擁有同樣< machineKey>配置的應(yīng)用程序也可以識(shí)別此cookie為有效的權(quán)限票據(jù)。所以在其他擁有同樣< machineKey>配置的應(yīng)用程序中就不再需要第二次登陸了。
由于< machineKey>信息是敏感的,你需要加密配置文件中的此節(jié)信息。為了實(shí)現(xiàn)這個(gè)目標(biāo),我將使用ConfigurationManager類和他的方法。這里還有一個(gè)類SectionInformation,包含有配置中單個(gè)配置節(jié)的元數(shù)據(jù)。此類中有個(gè)方法ProtectSection(),用來解密你的配置文件的配置節(jié)。
ASP.NET2.0中單點(diǎn)登錄配置:系統(tǒng)條件
·A web server running on Windows 2000 or later
·.NET Framework 2.0
·Visual Studio 2005
·Microsoft SQL Server 2005 Express Edition
現(xiàn)在讓我們來看看在我們的項(xiàng)目中發(fā)生了什么。我有一個(gè)站點(diǎn)(Aspalliance1)站點(diǎn)中包含一個(gè)登錄頁(yè)面”Login.aspx”.用戶可以通過此頁(yè)來進(jìn)行權(quán)限驗(yàn)證。在這個(gè)站點(diǎn)里還有一個(gè)頁(yè)面叫做”Default.aspx”,它有一個(gè)header和一些文本另外還有一個(gè)到Aspalliance2站點(diǎn)的鏈接。你將會(huì)看到一旦這個(gè)用戶登錄了,他可以導(dǎo)航到其他站點(diǎn)而不需要第二次登陸。這里還有一個(gè)安置有兩個(gè)加密和解密的按鈕的頁(yè)面”Encryption.aspx”,用來加密和解密配置文件。
就像我之前所說的那樣,你可以通過在你的web配置文件中一點(diǎn)點(diǎn)小小的配置實(shí)現(xiàn)跨應(yīng)用程序訪問。在web.config文件中,有一個(gè)名為< system.web>的配置節(jié)。我們將對(duì)< system.web>做相同的配置,只需要將配置節(jié)< machineKey>和它的值放到< system.web>配置節(jié)中。< machineKey>有一些屬性,我將要去配置他們。首先,就是指定用來驗(yàn)證的加密類型。validationKey 定義了用來驗(yàn)證解密數(shù)據(jù)的key,decryptionKey定義了用來加密和解密的數(shù)據(jù)的key,抑或是key生成的過程。
清單 1: 配置web.config中的machineKey
- < machineKey
- validationKey="282487E295028E59B8F411ACB689CCD6F39DDD21E6055A3EE480424315994760ADF
- 21B580D8587DB675FA02F79167413044E25309CCCDB647174D5B3D0DD9141"
- decryptionKey="8B6697227CBCA902B1A0925D40FAA00B353F2DF4359D2099"
- validation="SHA1"/>
這個(gè)樣例代碼并沒有被加密,并且它不會(huì)被發(fā)布到服務(wù)器上。因?yàn)樘幱诎踩紤],發(fā)布到服務(wù)器的< machineKey>的加密是非常重要的。你可以在清單2中看到加密后的< machineKey>。
清單 2: web.config 中加密后的machineKey
- < machineKeyconfigProtectionProvider="RsaProtectedConfigurationProvider">
- < EncryptedDataType="http://www.w3.org/2001/04/xmlenc#Element"
- xmlns="http://www.w3.org/2001/04/xmlenc#">
- < EncryptionMethodAlgorithm="http://www.w3.org/2001/04/xmlenc#tripledes-cbc" />
- < KeyInfoxmlns="http://www.w3.org/2000/09/xmldsig#">
- < EncryptedKeyxmlns="http://www.w3.org/2001/04/xmlenc#">
- < EncryptionMethodAlgorithm="http://www.w3.org/2001/04/xmlenc#rsa-1_5" />
- < KeyInfoxmlns="http://www.w3.org/2000/09/xmldsig#">
- < KeyName>Rsa Key< /KeyName>
- < /KeyInfo>
- < CipherData>
- < CipherValue>
- lm3mfPX/94Zm3HgdbsmKiIxbrWM14t3/ugxs40BFOAHbIaCtwQ3gVQusFtOFVUoNVny01kgBCeh10rVEId
- djNZ/8luBNoCbHm8OLjgPLHVrT+G0c/LRpESJk2ni/Jy2sWKXlgejgSQ1W5NE53GZtG3s9hu+nk4OWxntS
- 6z3v7AM=
- < /CipherValue>
- < /CipherData>
- < /EncryptedKey>
- < /KeyInfo>
- < CipherData>
- < CipherValue>
- BCEGUV/dh1Imbcm5vn0Kn8NrD+EX+KemenR7x+VekwT1ZO6y5+jRyF4RDWMJCfJ1jHC36+MAfCdHuXN0rP
- B6hu5YUtX9VA5q5N0NGrs9AIpG+0ihuuS3HDzQe3P6nlI30m1h0pmL1yJBovY0i6fbCA6++GT2MdwCLERk
- +PVWmoq7p1q97n5pNzNqhVKCX45lhS5ySVS+MjJXVeTrcatftpvaUcjLsNcL2kMerzf5w/SU3AbLEuY04w
- dgYWX5tWzxqeUcghdlWLD0tQi8qyyfVfzXPYozR5sspWHdgqmAycrACHN2dcONWPjT4BanRWb1ouKuP8K+
- 0CEFE/Hj2ChpYw==
- < /CipherValue>
- < /CipherData>
- < /EncryptedData>
- < /machineKey>
你可以通過Configuration、SectionInformation兩個(gè)類來加密你的配置文件。為了加密和解密你的< machineKey>讓我們來寫一些代碼吧。SectionInformation類有一個(gè)方法ProtectSection(),可以得到一個(gè)描繪Protection Provider的字符串比如"RSAProctedConfigurationProvider",并且加密這個(gè)配置節(jié)。這里還有一個(gè)Boolean類型的屬性ForceSave,當(dāng)需要配置類的save方法保存配置文件時(shí)需要將它設(shè)置為true。這里有"Encryption.aspx"頁(yè)面的代碼,頁(yè)面中包含有兩個(gè)按鈕來加密和解密配置文件。
清單 3:web配置文件的加密代碼
- protected void btnEncrypt_Click(object sender, EventArgs e)
- {
- try
- {
- Configuration config = WebConfigurationManager.OpenWebConfiguration(
- "/Aspalliance1 ");
- ConfigurationSection machineKeySection = config.GetSection(
- "system.web/machineKey");
- machineKeySection.SectionInformation.ProtectSection(
- "RSAProtectedConfigurationProvider");
- machineKeySection.SectionInformation.ForceSave = true;
- config.Save();
- Response.Write("< h2 style='color:red'>Encryption Succeed< /h2>");
- }
- catch (Exception ex)
- {
- Response.Write("< h2 style='color:red'>Error while encrypting< /h2>< br/>");
- Response.Write(ex.Message);
- }
- }
清單 4: web配置文件的解密代碼
- protected void btnDecrypt_Click(object sender, EventArgs e)
- {
- try
- {
- Configuration config = WebConfigurationManager.OpenWebConfiguration(
- "/Aspalliance1 ");
- ConfigurationSection machineKeySection = config.GetSection(
- "system.web/machineKey");
- machineKeySection.SectionInformation.UnprotectSection();
- machineKeySection.SectionInformation.ForceSave = true;
- config.Save();
- Response.Write("< h2 style='color:red'>Decryption Succeed< /h2>");
- }
- catch (Exception ex)
- {
- Response.Write("< h2 style='color:red'>Error while decrypting< /h2>< br/>");
- Response.Write(ex.Message);
- }
- }
現(xiàn)在你必須在這個(gè)站點(diǎn)中設(shè)置相同的配置。首先你需要更改你的窗體驗(yàn)證部分的loginUrl,這個(gè)窗體將被用來將匿名用戶跳轉(zhuǎn)到”Login.aspx”頁(yè)。只是,現(xiàn)在它將把用戶重定向到Aspalliance1站點(diǎn)中的”Login.aspx”頁(yè)。
清單 5: 設(shè)置 web.config中的驗(yàn)證節(jié)
- < authentication mode="Forms">
- < forms loginUrl="http://localhost/Aspalliance1/login.aspx"name=".ASPXAUTH"/>
- < /authentication>
如果你想實(shí)現(xiàn)跨程序登錄你的好多站點(diǎn)時(shí),最重要的一點(diǎn)就是你必須把你的兩個(gè)或更多的站點(diǎn)配置為相同的< machineKey>。所以我只需要拷貝并粘貼Aspalliance1 站點(diǎn)中的< machineKey>配置節(jié)到Aspalliance2站點(diǎn)?,F(xiàn)在都已經(jīng)準(zhǔn)備好了,你可以測(cè)試你的站點(diǎn)了。
清單 6: 設(shè)置web.config 中的 machineKey
- < machineKey
- validationKey="282487E295028E59B8F411ACB689CCD6F39DDD21E6055A3EE480424315994760ADF
- 21B580D8587DB675FA02F79167413044E25309CCCDB647174D5B3D0DD9141"
- decryptionKey="8B6697227CBCA902B1A0925D40FAA00B353F2DF4359D2099"
- validation="SHA1"/>
[下載]
測(cè)試這個(gè)站點(diǎn)的話,可以使用用戶名:Admin密碼:123456&來登錄。
這個(gè)下載附件中有一個(gè)VS 2005項(xiàng)目,其中包含有兩個(gè)站點(diǎn):aspalliance1 and aspalliance2.
要安裝這個(gè)實(shí)例的話,你需要?jiǎng)?chuàng)建兩個(gè)IIS虛擬目錄命名為:aspalliance1 和 aspalliance2,并將地址指向相應(yīng)的文件夾。你也可以通過Visual Studio 2005打開站點(diǎn)。
當(dāng)用戶要交叉訪問你的多個(gè)站點(diǎn)時(shí),他必須重復(fù)登陸實(shí)在是麻煩。所以,如果只讓用戶登錄一次,那會(huì)是非常棒的。實(shí)現(xiàn)這些,你只需要給你的"web.config" 文件增加具有相同值的< machineKey>配置。并且處于安全考慮,我建議你加密這個(gè)配置節(jié)。這個(gè)加密方法在SectionInformation類中通過ProtectSection()方法被重寫了。以上便是ASP.NET2.0中單點(diǎn)登錄的實(shí)現(xiàn)方法。
【編輯推薦】