日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

翻译:Single Sign-On for Everyone

發(fā)布時間:2025/7/14 编程问答 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 翻译:Single Sign-On for Everyone 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

?

前一陣寫了一篇Blog,給出了一些SSO的資料(http://www.cnblogs.com/AndersLiu/archive/2007/05/25/760041.html)。現(xiàn)在把其中的一篇翻譯出來。

翻譯:Single Sign-On for Everyone
原文地址:http://bbs.hidotnet.com/22656/ShowPost.aspx

單點登錄(Single Sign-OnSSO)是這些天的熱點話題。我的很多客戶都有多個Web應(yīng)用,運行在不同子域的不同.NET Framework版本中,甚至是不同的域中。他們都希望用戶能夠只登錄一次,就能在各個不同的Web站點中保持登錄狀態(tài)。今天我們來一起看看如何在各種不同的場景中實現(xiàn)SSO。我們首先從最簡單的情況開始,然后逐步構(gòu)建它:

1. 虛擬子目錄中的父、子應(yīng)用之間的SSO
2. 使用不同授權(quán)憑證(用戶名映射)的SSO
3. 同一域下的兩個子域中的Web應(yīng)用之間的SSO
4. 不同.NET版本下的應(yīng)用之間的SSO
5. 不同域之眾的兩個應(yīng)用之間的SSO
6. 混合模式驗證(FormsWindows)中的SSO

1. 虛擬子目錄中的父、子應(yīng)用之間的SSO

  假設(shè)有兩個.NET應(yīng)用——FooBar,并且Bar位于Foo的一個虛擬子目錄中(http://foo.com/bar)。兩個應(yīng)用都實現(xiàn)了Forms驗證。實現(xiàn)Forms驗證需要重寫Application_AuthenticateRequest,在這里進行驗證,并在驗證成功后調(diào)用FormsAuthentication.RedirectFromLoginPage,將登錄的用戶名(或系統(tǒng)中用于標識用戶的其他信息)作為參數(shù)傳遞進去。在ASP.NET中,登錄用戶狀態(tài)通過保存在客戶端Cookie中進行持久化。當調(diào)用RedirectFromLoginPage時,就會創(chuàng)建一個Cookie,其中包含了加密的、帶有登錄用戶名的FormsAuthenticationTicketWeb.Config中有一節(jié)用于定義如何創(chuàng)建該Cookie

<authentication?mode="Forms">?

????
<forms?name=".FooAuth"?protection="All"?timeout="60"?loginUrl="login.aspx"?/>?

</authentication>?


<authentication?mode="Forms">?

????
<forms?name=".BarAuth"?protection="All"?timeout="60"?loginUrl="login.aspx"?/>?

</authentication>?
  這里最重要的兩個屬性是nameprotection。如果在FooBar中,這兩個屬性是匹配的,那么它們就能在同樣的保護級別上使用相同的Cookie,也就實現(xiàn)了SSO

<authentication?mode="Forms">?

????
<forms?name=".SSOAuth"?protection="All"?timeout="60"?loginUrl="login.aspx"?/>?

</authentication>
  當將protection屬性設(shè)置為“All”以后,會同時對Cookie進行加密盒驗證(通過散列值)。默認的驗證和加密密鑰存儲在Machine.Config中,并且可以在應(yīng)用程序的Web.Config中重寫。其默認值為:

<machineKey?validationKey="AutoGenerate,IsolateApps"?decryptionKey="?AutoGenerate,IsolateApps"?validation="SHA1"?/>
  IsolateApps意味著將為每個應(yīng)用程序都生成一個不同的密鑰。我們不能這樣做。為了在所有應(yīng)用程序中都能加密/解謎Cookie,需要移除IsolateApps屬性,并為使用SSO的所有應(yīng)用程序指定相同的具體密鑰:

<machineKey?validationKey="F9D1A2D3E1D3E2F7B3D9F90FF3965ABDAC304902"?decryptionKey="F9D1A2D3E1D3E2F7B3D9F90FF3965ABDAC304902F8D923AC"?validation="SHA1"?/>
  如果你正在針對不同的用戶存儲進行驗證,這就是所有需要做的——對Web.Config的一點修改。

2. 使用不同授權(quán)憑證(用戶名映射)的SSO

  但是,如果Foo應(yīng)用使用其自己的數(shù)據(jù)庫,而Bar應(yīng)用程序使用Membership API或其他形式的驗證呢?在這種情況下,為Foo創(chuàng)建的Cookie并不適用于Bar,因為Bar并不理解其中包含的用戶名。

  為了使其工作,需要創(chuàng)建第二個驗證Cookie,專門用于Bar應(yīng)用。還需要一種方式來將Foo用戶映射到Bar用戶。假設(shè)Foo應(yīng)用中登錄了一個“John Doe”用戶,并且經(jīng)過檢測發(fā)現(xiàn)這個用戶在Bar應(yīng)用中的標識是“johnd”。在Foo的驗證方法中需要添加下面的代碼:

FormsAuthenticationTicket?fat?=?new?FormsAuthenticationTicket(1,?"johnd",?DateTime.Now,?DateTime.Now.AddYears(1),?true,?"");?

HttpCookie?cookie?
=?new?HttpCookie(".BarAuth");?

cookie.Value?
=?FormsAuthentication.Encrypt(fat);?

cookie.Expires?
=?fat.Expiration;?

HttpContext.Current.Response.Cookies.Add(cookie);?


FormsAuthentication.RedirectFromLoginPage(
"John?Doe");?
  硬編碼的用戶名僅僅用于演示目的。這段代碼為Bar應(yīng)用創(chuàng)建了FormsAuthenticationTicket,并用從Bar應(yīng)用的上下文中找到的用戶名對其進行了填充。然后調(diào)用了RedirectFromLoginPageFoo應(yīng)用創(chuàng)建了正確的驗證Cookie。如果你將兩個應(yīng)用程序的驗證Cookie名字改成了相同的(見前面的示例),那么要注意現(xiàn)在他們是不同的了,我們無需再為每個站點使用相同的Cookie了:

<authentication?mode="Forms">?

????
<forms?name=".FooAuth"?protection="All"?timeout="60"?loginUrl="login.aspx"?slidingExpiration="true"/>?

</authentication>?


<authentication?mode="Forms">?

????
<forms?name=".BarAuth"?protection="All"?timeout="60"?loginUrl="login.aspx"?slidingExpiration="true"/>?

</authentication>?
  現(xiàn)在,只要用戶登錄到Foo,他就會被映射到Bar用戶,并在會隨著Foo驗證票據(jù)創(chuàng)建一個Bar驗證票據(jù)。如果希望相反的方向也能工作,只需在Bar應(yīng)用中添加類似的代碼即可:

FormsAuthenticationTicket?fat?=?new?FormsAuthenticationTicket(1,?"John?Doe",?DateTime.Now,?DateTime.Now.AddYears(1),?true,?"");?
HttpCookie?cookie?
=?new?HttpCookie(".FooAuth");?
cookie.Value?
=?FormsAuthentication.Encrypt(fat);?
cookie.Expires?
=?fat.Expiration;?
HttpContext.Current.Response.Cookies.Add(cookie);?
FormsAuthentication.RedirectFromLoginPage(
"johnd");?
  但仍然要確保Web.Config中的<machineKey>元素中為兩個應(yīng)用提供了匹配的驗證和加密密鑰。

3. 同一域下的兩個子域中的Web應(yīng)用之間的SSO

  現(xiàn)在假設(shè)FooBar配置為在不同的域http://foo.comhttp://bar.foo.com中運行。前面的代碼都不能使用了,因為Cookies將被存放到不同的文件中,并且應(yīng)用程序彼此看不到(對方的Cookie)。為了使其能夠工作,我們需要創(chuàng)建域級別的Cookies,并使其對所有子域可見。這樣我們就不能使用RedirectFromLoginPage方法了,因為它不適合創(chuàng)建域級別的Cookie。我們可以手動完成這一工作:

FormsAuthenticationTicket?fat?=?new?FormsAuthenticationTicket(1,?"johnd",?DateTime.Now,?DateTime.Now.AddYears(1),?true,?"");?

HttpCookie?cookie?
=?new?HttpCookie(".BarAuth");?

cookie.Value?
=?FormsAuthentication.Encrypt(fat);?

cookie.Expires?
=?fat.Expiration;?

cookie.Domain?
=?".foo.com";??//?Highlight?

HttpContext.Current.Response.Cookies.Add(cookie);?


FormsAuthenticationTicket?fat?
=?new?FormsAuthenticationTicket(1,?"John?Doe",?DateTime.Now,?DateTime.Now.AddYears(1),?true,?"");?

HttpCookie?cookie?
=?new?HttpCookie(".FooAuth");?

cookie.Value?
=?FormsAuthentication.Encrypt(fat);?

cookie.Expires?
=?fat.Expiration;?

cookie.Domain?
=?".foo.com";??//?Highlight?

HttpContext.Current.Response.Cookies.Add(cookie);?


  注意高亮顯示的行(Anders Liu:為了避免格式問題,我使用的是注釋“// Highlight”)。通過明確地將Cookie的域設(shè)定為“.foo.com”,可以確保在http://foo.comhttp://bar.foo.com以及其他子域中都能看到該Cookie。你也可以將Bar的驗證Cookie域設(shè)置為“bar.foo.com”。這樣更加安全,因為其他子域看不到它。注意RFC 2109Cookie域值中要求兩個periods,因此我們在前面添加了一個period——“.foo.com”。

  另外,確保在每個應(yīng)用的Web.Config中使用相同的<machineKey>元素。只有一種特殊情況,接下來的小節(jié)將探討這一情況。

4.
不同.NET版本下的應(yīng)用之間的SSO

  有一種可能是FooBar應(yīng)用運行在不同版本的.NET中。這是前面的例子就不能工作了。這是因為ASP.NET 2.0使用了不同的加密方法對驗證票據(jù)進行加密。ASP.NET 1.1使用的是3DES,而ASP.NET 2.0使用的是AES。幸運的是,ASP.NET 2.0為了向后兼容,提供了一個新的屬性:

<machineKey?validationKey="F9D1A2D3E1D3E2F7B3D9F90FF3965ABDAC304902"?decryptionKey="F9D1A2D3E1D3E2F7B3D9F90FF3965ABDAC304902F8D923AC"?validation="SHA1"?decryption="3DES"?/>
  設(shè)置decryption="3DES"可以讓ASP.NET 2.0使用老的加密方法,這樣Cookies就又匹配了。不要向ASP.NET 1.1Web.Config中添加這個屬性,否則會導(dǎo)致錯誤。

5. 不同域之眾的兩個應(yīng)用之間的SSO

  至此為止我們成功地創(chuàng)建了共享的驗證Cookie,但如果FooBar位于不同的域——http://foo.comhttp://bar.com——中呢?它們不可能共享Cookie,也不能彼此創(chuàng)建第二Cookie。這種情況下,每個站點需要創(chuàng)建自己的Cookies,并調(diào)用其他站點來驗證用戶是否已經(jīng)在別處登錄了。完成這一工作的一種方法就是通過一些列的重定向。

  為了實現(xiàn)這一目的,我們分別在兩個Web站點中都創(chuàng)建一個特殊的頁面(我們稱之為sso.aspx)。這個頁面的目的就是檢查其域中是否存在Cookie,并返回登錄的用戶名,這樣其他應(yīng)用可以在對應(yīng)的域中創(chuàng)建類似的Cookie。下面是來自Bar.comsso.aspx

<%@?Page?Language="C#"?%>?


<script?language="C#"?runat="server">?



void?Page_Load()?

{?

????
//?this?is?our?caller,?we?will?need?to?redirect?back?to?it?eventually?

????UriBuilder?uri?
=?new?UriBuilder(Request.UrlReferrer);?


????HttpCookie?c?
=?HttpContext.Current.Request.Cookies[".BarAuth"];?


????
if?(c?!=?null?&&?c.HasKeys)?//?the?cookie?exists!?

????
{?

????????
try?

????????
{?

????????????string?cookie?
=?HttpContext.Current.Server.UrlDecode(c.Value);?

????????????FormsAuthenticationTicket?fat?
=?FormsAuthentication.Decrypt(cookie);?????????


????????????uri.Query?
=?uri.Query?+?"&ssoauth="?+?fat.Name;?//?add?logged-in?user?name?to?the?query?

????????}
?

????????
catch?

????????
{?

????????}
?

????}
?

????Response.Redirect(uri.ToString());?
//?redirect?back?to?the?caller?

}
?


</script>?


  這個頁面總是會重定向回調(diào)用方。如果Bar.com中存在驗證Cookie,會解密用戶名并通過查詢字符串中的ssoauth參數(shù)返回。

  在另外一端(Foo.com),我們需要像http請求處理流水線中插入一些代碼。可以在Application_BeginRequest事件中或者在一個自定義的HttpHandlerHttpModule中。其用意在于在所有的頁面請求的盡可能早的地方檢驗驗證Cookie是否存在:

1)
如果Foo.com中存在驗證Cookie,繼續(xù)處理請求。此時用戶已登錄Foo.com
2) 如果驗證Cookie不存在,重定向到Bar.com/sso.aspx
3) 如果當前請求從Bar.com/sso.aspx重定向回來,分析ssoauth參數(shù)并在必要時創(chuàng)建驗證Cookie

  這看起來相當簡單,但要注意無限循環(huán):

//?see?if?the?user?is?logged?in?

HttpCookie?c?
=?HttpContext.Current.Request.Cookies[".FooAuth"];?


if?(c?!=?null?&&?c.HasKeys)?//?the?cookie?exists!?

{?

????
try?

????
{?

????????
string?cookie?=?HttpContext.Current.Server.UrlDecode(c.Value);?

????????FormsAuthenticationTicket?fat?
=?FormsAuthentication.Decrypt(cookie);?

????????
return;?//?cookie?decrypts?successfully,?continue?processing?the?page?

????}
?

????
catch?

????
{?

????}
?

}
?


//?the?authentication?cookie?doesn't?exist?-?ask?Bar.com?if?the?user?is?logged?in?there?

UriBuilder?uri?
=?new?UriBuilder(Request.UrlReferrer);?


if?(uri.Host?!=?"bar.com"?||?uri.Path?!=?"/sso.aspx")?//?prevent?infinite?loop?

{?

????Response.Redirect(http:
//bar.com/sso.aspx);?

}
?

else?

{?

????
//?we?are?here?because?the?request?we?are?processing?is?actually?a?response?from?bar.com?


????
if?(Request.QueryString["ssoauth"]?==?null)?

????
{?

????????
//?Bar.com?also?didn't?have?the?authentication?cookie?

????????
return;?//?continue?normally,?this?user?is?not?logged-in?

????}
?else?

????
{?


????????
//?user?is?logged?in?to?Bar.com?and?we?got?his?name!?

????????
string?userName?=?(string)Request.QueryString["ssoauth"];?


????????
//?let's?create?a?cookie?with?the?same?name?

????????FormsAuthenticationTicket?fat?
=?new?FormsAuthenticationTicket(1,?userName,?DateTime.Now,?DateTime.Now.AddYears(1),?true,?"");?

????????HttpCookie?cookie?
=?new?HttpCookie(".FooAuth");?

????????cookie.Value?
=?FormsAuthentication.Encrypt(fat);?

????????cookie.Expires?
=?fat.Expiration;?

????????HttpContext.Current.Response.Cookies.Add(cookie);?

????}
?

}
?



  兩個站點都同樣需要這段代碼,但要在每個站點中使用正確的Cookie名字(.FooAuth vs. .BarAuth)。由于實際上并沒有共享Cookie,所以應(yīng)用程序可以具有不同的<machineKey>元素。無需同步加密和驗證密鑰。

  很多人可能比較擔(dān)心在查詢字符串中傳遞用戶名所帶來的安全隱患。很多方法可以對其進行保護。首先,要檢查引用方,不接受來自任何源的ssoauth參數(shù),但除了bar.com/sso.asp(或foo.com/sso.aspx)。其次,可以很容易地使用共享密鑰對用戶名進行加密。如果FooBar使用了不同的驗證機制,也可以用類似的方式傳遞用戶的附加信息(例如email地址)。

6.
混合模式驗證(FormsWindows)中的SSO

  到現(xiàn)在為止,我們一直在處理Forms驗證的情況。但如果我們希望對于Internet用戶首先采用Forms驗證,如果驗證失敗,再檢查是否是NT域中的Intranet用戶并進行驗證。理論上,我們可以通過下面的參數(shù)來檢查是否與請求關(guān)聯(lián)了一個Windows已登錄用戶:

Request.ServerVariables["LOGON_USER"]?


  然而,除非站點禁用了匿名訪問,否則該值一直為空。我們可以在IIS控制面板中禁用匿名訪問,并啟用集成Windows驗證。這樣LOGON_USER值中將包含已登錄的Intranet用戶的NT域名。但是所有的Internet用戶將面臨Windows用戶名和密碼的挑戰(zhàn)。這不爽。我們希望Internet用戶可以通過Forms驗證進行登錄,而當失敗的時候再檢測其Windows域憑證。

  解決這一問題的一個方法是,為Intranet用戶提供一個特殊的入口頁,在這里啟用集成Windows驗證,驗證域用戶,然后創(chuàng)建一個Forms Cookie并導(dǎo)航到主站點。我們甚至可以通過Server.Transfer來隱藏Intranet用戶訪問了不同的頁面這一事實。

  還有一種簡單的解決方案。因為IIS處理驗證過程,如果一個Web站點啟用了匿名訪問,IIS會將請求正確地傳遞給ASP.NET 運行時。它不會嘗試執(zhí)行任何類型的驗證。然而,如果請求的結(jié)果是一個驗證錯誤(401),IIS會嘗試特定于該站點的另外一種驗證方法。你可以同時啟用匿名訪問和集成Windows驗證,然后再Forms驗證失敗后執(zhí)行下面的代碼:

if?(System.Web.HttpContext.Current.Request.ServerVariables["LOGON_USER"]?==?"")?{?

????System.Web.HttpContext.Current.Response.StatusCode?
=?401;?

????System.Web.HttpContext.Current.Response.End();?

}
?

else?

{?

????
//?Request.ServerVariables["LOGON_USER"]?has?a?valid?domain?user?now!?

}
?


  這段代碼執(zhí)行時,會首先檢測域用戶并得到一個空的字符串。然后它會終止當前請求并向IIS返回驗證錯誤(401)。這將導(dǎo)致IIS使用另外一種驗證機制,在這種情況下是集成Windows驗證。如果用戶已經(jīng)登錄到域,請求會被重復(fù)一次,此時會填充NT域用戶信息。如果用戶沒有登錄到域,他將有三次機會輸入Windows用戶名/密碼。如果用戶無法在三次嘗試之內(nèi)完成登錄,他會得到403錯誤(拒絕訪問)。

小結(jié)


  我們討論了在兩個ASP.NET應(yīng)用之間進行的各種場景的單點登錄。當然也可以實現(xiàn)不同平臺間的異構(gòu)系統(tǒng)上的SSO。其思路是同樣的,但實現(xiàn)起來可能需要一些創(chuàng)造性的想法。

轉(zhuǎn)載于:https://www.cnblogs.com/AndersLiu/archive/2007/06/20/790894.html

總結(jié)

以上是生活随笔為你收集整理的翻译:Single Sign-On for Everyone的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 99精品欧美一区二区蜜桃免费 | 看免费的毛片 | 大尺度网站在线观看 | xxxwww国产| 超碰免费人人 | 久久免费大片 | 美女在线网站 | 日韩视频在线观看一区 | 男插女av | 亚洲国产专区 | 欧美日韩aa | 中国女人做爰视频 | jizzjizzjizz亚洲女 | 麻豆91在线 | 日韩在线精品强乱中文字幕 | 中文字幕亚洲欧美日韩在线不卡 | 成人免费观看视频 | 黄wwwww | 久久影院精品 | 狂野欧美| 欧美人与性动交α欧美片 | 亚洲高清在线播放 | 欧美视频观看 | 婷婷伊人综合 | 亚洲网站免费 | 麻豆传媒网址 | 夜夜夜操操操 | 日韩av无码中文字幕 | 久久久久看片 | 午夜精品美女久久久久av福利 | 国产精品视频免费在线观看 | 亚洲手机在线观看 | 久操福利视频 | 中文字幕亚洲日本 | 伊伊综合网 | www超碰 | 午夜影院在线播放 | 日本精品在线视频 | 成人免费av片| 一级免费黄色 | 午夜在线免费观看视频 | 亚洲天堂男人av | 成人免费观看视频网站 | 欧美日韩tv| 欧美顶级metart裸体全部自慰 | www.婷婷.com | 欧美中文| 国产精品日韩欧美一区二区三区 | 伊人精品一区二区三区 | v天堂在线 | 九九九热视频 | 密乳av | 成人亚洲视频 | 香蕉蜜桃视频 | 亚洲国产无线乱码在线观看 | 精品视频一区二区在线观看 | 国产精品99久久久久久宅男 | 亚洲人成人无码网www国产 | 国产一级大片在线观看 | 色屁屁草草影院ccyycom | 亚洲人成在线播放 | 一级片在线观看视频 | 午夜影院一区二区三区 | 精品人妻无码一区二区 | 欧美极品喷水 | 99蜜桃臀久久久欧美精品网站 | 91看片黄 | 精品免费一区二区 | 极品销魂美女一区二区 | 新av在线 | 91美女在线| 亚洲精品第五页 | 一区二区三区影院 | 亚洲做受高潮无遮挡 | 8x国产一区二区三区精品推荐 | 九九人人 | 欧美精品一区二区三区在线 | 亚洲欧美日韩精品在线 | 国产裸体永久免费无遮挡 | 亚洲一区二区三区电影 | 久久精品国产成人av | 日韩精品一区二区av | 亚洲在线a| 亚洲成人免费 | 香蕉伊思人视频 | 91丝袜呻吟高潮美腿白嫩在线观看 | 九九免费在线视频 | 一区精品在线观看 | 激情久久五月 | 丰满秘书被猛烈进入高清播放在 | 国产亚洲精品一区二区三区 | 国产精品视频一 | 99精品一级欧美片免费播放 | 西西大胆午夜视频 | 国产成人综合一区二区三区 | 亚洲mv一区| 黄色av网址在线 | 国产精品成人一区二区三区电影毛片 | 亚洲图片 欧美 |