空間站

          北極心空

            BlogJava :: 首頁(yè) :: 聯(lián)系 :: 聚合  :: 管理
            15 Posts :: 393 Stories :: 160 Comments :: 0 Trackbacks

          摘要:

          OpenID是一種開(kāi)放、離散式的用于用戶數(shù)字標(biāo)識(shí)的開(kāi)源框架。在網(wǎng)絡(luò)應(yīng)用日益充斥的今天,作為終端用戶的我們不得不在每個(gè)網(wǎng)站上設(shè)置帳號(hào),并管理眾多的帳號(hào)。而采用OpenID技術(shù)的話,你就無(wú)須再管理這些相互獨(dú)立的帳號(hào),而是通過(guò)認(rèn)證服務(wù)器管理自己唯一的身份標(biāo)識(shí)。本文將詳細(xì)解釋OpenID技術(shù)框架以及如何使用Java進(jìn)行開(kāi)發(fā)。


           

          OpenID使用手冊(cè)

          作者:cleverpig
          image


          什么是OpenID?

          OpenID是一種開(kāi)放、離散式的用于用戶數(shù)字標(biāo)識(shí)的開(kāi)源框架。

          請(qǐng)讓我們思考自己所擁有的在線帳號(hào)種類:博客、wiki、to-do list、個(gè)人相冊(cè)。在網(wǎng)絡(luò)應(yīng)用日益充斥的今天,這些個(gè)人在線帳號(hào)可謂不勝枚舉,而對(duì)帳號(hào)的需要也同樣無(wú)處不在,乃至當(dāng)我們想在好友博客上進(jìn)行評(píng)論時(shí)都需要注冊(cè)成為該博客系統(tǒng)的用戶。于是作為終端用戶,我們不得不在每個(gè)網(wǎng)站上設(shè)置帳號(hào),并管理眾多的帳號(hào)。而采用OpenID技術(shù)的話,你就無(wú)須再管理這些相互獨(dú)立的帳號(hào),而是通過(guò)認(rèn)證服務(wù)器管理自己唯一的身份標(biāo)識(shí)。

          OpenID常見(jiàn)的應(yīng)用場(chǎng)景:某用戶試圖登錄一個(gè)外部網(wǎng)站。與提交用戶名和密碼的方式不同,他只提交了屬于自己的一個(gè)URL,例如:http://johnsmith.example.com/

          這個(gè)URL即指向了用戶的OpenID認(rèn)證服務(wù)器,同時(shí)又是用戶的身份標(biāo)識(shí)。因此外部網(wǎng)站使用此URL便可以找到用戶的認(rèn)證服務(wù)器,并詢問(wèn)認(rèn)證服務(wù)器:“該用戶聲稱他擁有此URL。而這個(gè)URL說(shuō)明了你負(fù)責(zé)認(rèn)證工作,那么請(qǐng)告訴我,該用戶能否訪問(wèn)我的站點(diǎn)?”。認(rèn)證服務(wù)器將提示用戶登入認(rèn)證系統(tǒng),并詢問(wèn)用戶是否允許和外部網(wǎng)站進(jìn)行認(rèn)證。如果用戶同意的話,那么認(rèn)證服務(wù)器將通知外部網(wǎng)站——用戶已經(jīng)通過(guò)認(rèn)證。在上面,我們通過(guò)擬人化的表達(dá)方式來(lái)形象生動(dòng)地詮釋整個(gè)認(rèn)證請(qǐng)求/回應(yīng)過(guò)程。

          用戶可以使用同一個(gè)URL用作在任何支持OpenID認(rèn)證的外部網(wǎng)站中使用的標(biāo)識(shí)。這正是OpenID與其它傳統(tǒng)認(rèn)證方式的最大不同。通過(guò)使用URL,可以使外部站點(diǎn)非常容易地獲取到負(fù)責(zé)認(rèn)證工作的服務(wù)器位置。而只有認(rèn)證服務(wù)器才需要輸入密碼來(lái)驗(yàn)證用戶身份。其它希望驗(yàn)證用戶身份的站點(diǎn)都將詢問(wèn)用戶所注冊(cè)的認(rèn)證服務(wù)器。如果你正在使用支持OpenID的門戶站點(diǎn)(比如AOL),那么你就可以使用現(xiàn)成的AOL即時(shí)消息登錄帳號(hào)來(lái)登錄AOL站點(diǎn),而無(wú)需另外注冊(cè)。因此,我們可以猜想Google和Yahoo也許已經(jīng)開(kāi)始著手建造他們的OpenID服務(wù)。

          你一定想知道OpenID是如何實(shí)現(xiàn)分散化服務(wù)的?由于用戶具有選擇OpenID服務(wù)提供者的權(quán)利,因此你會(huì)在最初選擇AOL作為OpenID提供者,而過(guò)一段時(shí)間后,可能覺(jué)得希望更換到另外一個(gè)OpenID提供者,此時(shí)你所需要做的就是修改以下的HTML標(biāo)簽:
          <link rel="openid.server" >

          保存這些link元數(shù)據(jù)的最常見(jiàn)位置就是個(gè)人站點(diǎn)(比如博客)的根頁(yè)面。

          如何使用OpenID?

          OpenID絕妙地解決了多個(gè)帳號(hào)同步問(wèn)題,但并不僅僅如此。例如,你可以利用它建立跨應(yīng)用、跨域的單點(diǎn)登錄(Single sign-on)。如果你使用同一個(gè)OpenID登入了博客和個(gè)人相冊(cè),那么你只需要在登錄過(guò)程中進(jìn)行一次認(rèn)證。對(duì)于在此之后的每個(gè)需要登錄的應(yīng)用(在同一個(gè)session周期)只需提供OpenID,而不是傳統(tǒng)的用戶名和密碼。

          大多數(shù)OpenID提供者也提供了支持多個(gè)配置的功能。這樣你就可以使用“Bob Smith”登錄博客,而使用“Robert J Smith”登錄企業(yè)wiki。隨著OpenID提供者的日益成熟和OpenID功能上的提升,我們不久就會(huì)使用對(duì)來(lái)自伙伴公司OpenID認(rèn)證服務(wù)器主機(jī)名的用戶進(jìn)行認(rèn)證的服務(wù)。

          哪些網(wǎng)站支持OpenID?

          OpenID技術(shù)出現(xiàn)不久,便獲得了在眾多公共消費(fèi)站點(diǎn)的熱捧:DiggSix ApartZoomrAOL。其中AOL為老用戶提供了OpenID支持,使得六千五百萬(wàn)的登錄用戶在一日之內(nèi)就全部能夠使用OpenID。目前已經(jīng)具有超過(guò)九千五百萬(wàn)的用戶能夠使用OpenID登錄系統(tǒng),并且每天都有25至50個(gè)站點(diǎn)加入到支持OpenID規(guī)范的隊(duì)伍中。另外,OpenID增加了對(duì)Firefox3和微軟Windows Vista的支持。

          下面是實(shí)現(xiàn)了OpenID代碼庫(kù)的語(yǔ)言列表:
                  • C#
                  • C++
                  • Java
                  • Perl
                  • Python
                  • Ruby
                  • PHP
                  • Coldfusion

          OpenID社區(qū)維護(hù)了這些代碼庫(kù)的清單:http://openid.net/wiki/index.php/Libraries。在本文的后面,我們將討論到OpenID的Java實(shí)現(xiàn):OpenID4Java(http://www.openid4java.org)。

          OpenID協(xié)議綜述

          OpenID協(xié)議非常易于擴(kuò)展,下面的圖表展示了OpenID2.0草案的基本工作流程。它展示了在終端用戶、Relying Party站點(diǎn)(一個(gè)示例站點(diǎn))和OpenID服務(wù)提供者之間的交互過(guò)程(最常見(jiàn)的認(rèn)證流程)。
          image

          用戶登入外部站點(diǎn)的過(guò)程主要分為以下七個(gè)步驟:

          1. Relying Party站點(diǎn)請(qǐng)求用戶標(biāo)識(shí)

          此步驟非常簡(jiǎn)單:用戶提供一個(gè)字符串(以URL或者XRI格式)給外部站點(diǎn),使后者能夠識(shí)別用戶。

                  1.外部站點(diǎn)請(qǐng)求用戶發(fā)送標(biāo)識(shí)。通常使用帶有Open圖標(biāo)的文本輸入框、用于提交信息的按鈕組成的form來(lái)完成此功能。為了方便起見(jiàn),文本輸入框的name屬性應(yīng)為openid_identifier,這樣以便瀏覽器自動(dòng)將其識(shí)別為一個(gè)OpenID登錄form。
                  2.用戶輸入標(biāo)識(shí),標(biāo)識(shí)可能采用下面的形式:
                  • URI/URL (通過(guò)http或者h(yuǎn)ttps)
                  • XRI。XRI是一種廣義的、分散式的URI。它能用于任何使用URI的地方。XRI主要采用以下形式:xri://authority/path?query#fragment。了解更多關(guān)于XRI的信息請(qǐng)看:XRI語(yǔ)法規(guī)范

          用戶標(biāo)識(shí)類似這個(gè)樣子:http://myname.myhost.com/。外部站點(diǎn)經(jīng)常將OpenID logo放置到其登錄form上,這樣可以使你很快地辨別出是否使用OpenID。
          image
          用戶在點(diǎn)擊位于外部站點(diǎn)登錄頁(yè)面上的“Login”按鈕后便啟動(dòng)了認(rèn)證過(guò)程。

          2.“標(biāo)準(zhǔn)化”: Relying Party站點(diǎn)整理用戶標(biāo)識(shí)

          用戶輸入了標(biāo)識(shí)后,此標(biāo)識(shí)便由外部站點(diǎn)進(jìn)行整理(標(biāo)準(zhǔn)化)。由于標(biāo)識(shí)可能使用XRI或者URI格式,因此整理的過(guò)程非常復(fù)雜:
                  1.如果標(biāo)識(shí)以xri://、xri://$ip或者xri://$dns*開(kāi)頭,那么我們要去掉這些頭部標(biāo)記。
                  2.如果余下字符串中的第一個(gè)字符是XRI的全局上下文符號(hào)(=、@、+、 $、!),那么此字符串為標(biāo)準(zhǔn)的XRI標(biāo)識(shí)。否則,將被視為HTTP URL(如果http/https前綴沒(méi)有定義,我們需要為其添加上http://)。當(dāng)然,URL必須遵守URL命名規(guī)范。最終獲得的URL就是一個(gè)標(biāo)準(zhǔn)的URL標(biāo)識(shí)。

          下面是一些示例:
          image

          下面的流程圖描繪了標(biāo)準(zhǔn)化處理過(guò)程:
          image

          3.“發(fā)現(xiàn)”: Relying Party站點(diǎn)查詢與OpenID服務(wù)器進(jìn)行通訊的方式

          外部站點(diǎn)使用標(biāo)準(zhǔn)化的標(biāo)識(shí)來(lái)查詢用于發(fā)起請(qǐng)求所必須的信息。對(duì)于“發(fā)現(xiàn)”階段來(lái)講,其使用的解析協(xié)議和獲取的結(jié)果文檔都取決于在標(biāo)準(zhǔn)化階段決定的標(biāo)識(shí)類型。這正是OpenID2.0規(guī)范的特殊之處。
          image

          快速參考:

                  • XRI 解析:類似通過(guò)UDP將主機(jī)名解析為IP的DNS協(xié)議;它將XRI轉(zhuǎn)換為XRDS。其目的是提供一種將厚重、通用的XRI格式轉(zhuǎn)換為真實(shí)可用的描述符。

                  • YADIS協(xié)議:將URL連接到XRDS上。這是一種非常簡(jiǎn)單的協(xié)議,它將當(dāng)前的HTTP或者HTTPS URL直接指向XRDS。

                  • XRDS:一種基于XML的XRI資源描述符。它被設(shè)計(jì)用來(lái)提供關(guān)于XRI的可用的、描述性信息。在OpenID應(yīng)用場(chǎng)合中,XRDS用來(lái)描述OpenID服務(wù)器,并且使用“priority”參數(shù)標(biāo)識(shí)了用戶對(duì)服務(wù)器的優(yōu)選順序。在下面的示例中,http://www.livejournal.com/users/frank具有最高的優(yōu)先權(quán)(最低的數(shù)值):
          <?xml version="1.0" encoding="UTF-8"?>
          <xrds:XRDS xmlns:xrds="xri://$xrds" xmlns="xri://$xrd*($v*2.0)"
          xmlns:openid="http://openid.net/xmlns/1.0">
            <XRD>
              <Service priority="50">
                <Type>http://openid.net/signon/1.0</Type>
                <URI>http://www.myopenid.com/server</URI>
                <openid:Delegate>http://smoker.myopenid.com/</openid:Delegate>
              </Service>
              <Service priority="10">
                <Type>http://openid.net/signon/1.0</Type>
                <URI>http://www.livejournal.com/openid/server.bml</URI>      <openid:Delegate>http://www.livejournal.com/users/frank/</openid:Delegate>
              </Service>
              <Service priority="20">
                <Type>http://lid.netmesh.org/sso/2.0</Type>
                <URI>http://mylid.net/liddemouser</URI>
              </Service>
            </XRD>
          </xrds:XRDS>

                  • 使用HTML代碼。在HTML的<head>部分必須提供以下標(biāo)簽:
          <link rel="openid2.provider" />


          可選的,如果用戶使用委派(delegation)(就是用戶宣稱擁有一個(gè)不存在于該OpenID服務(wù)器上的本地標(biāo)識(shí)),則需要使用下面的標(biāo)簽:
          <link rel="openid2.local_id" />


          例如,某人正在使用openidprovider.com這個(gè)OpenID服務(wù)器來(lái)驗(yàn)證他在另一個(gè)OpenID服務(wù)器usersite.com上的身份,那么其本地標(biāo)識(shí)將使用類似user.openidprovider.com的形式。

          這個(gè)“發(fā)現(xiàn)”的過(guò)程允許外部站點(diǎn)知道兩件事,其中一件是外部站點(diǎn)如何與OpenID服務(wù)器進(jìn)行通訊:
                  1.OpenID提供者端點(diǎn)URL:OpenID提供者的最終URL(服務(wù)器URL)。
                  2.認(rèn)證協(xié)議版本: OpenID認(rèn)證使用的協(xié)議版本。

          作為可選的,如果用戶使用委派,那么外部站點(diǎn)將需要知道:
                  1.用戶宣稱的標(biāo)識(shí):此標(biāo)識(shí)為用戶宣稱屬于自己的。它是在登錄過(guò)程中用戶提供過(guò)的標(biāo)識(shí)。
                  2.本地標(biāo)識(shí)(OP-Local Identifier):用戶在其OpenID服務(wù)器上擁有的本地標(biāo)識(shí)。

          例如,用戶使用http://www.example.com/作為其標(biāo)識(shí),但外部網(wǎng)站實(shí)際上通過(guò)https://www.exampleprovider.com/endpoint/這個(gè)OpenID服務(wù)器來(lái)驗(yàn)證用戶標(biāo)識(shí)https://exampleuser.exampleprovider.com/。那么在對(duì)http://www.example.com/執(zhí)行發(fā)現(xiàn)的過(guò)程中,我們需要在XRDS文檔的最后一個(gè)XRD成員中提供下面的XML片段
          <Service xmlns="xri://$xrd*($v*2.0)">
            <Type>http://specs.openid.net/auth/2.0/signon</Type>
            <URI>https://www.exampleprovider.com/endpoint/</URI>
            <LocalID>https://exampleuser.exampleprovider.com/</LocalID>
          </Service>


          4. Relying Party站點(diǎn)建立與OpenID服務(wù)器之間的關(guān)聯(lián)(可選)

          通過(guò)在外部站點(diǎn)和OpenID服務(wù)器之間的關(guān)聯(lián)(association),我們可以建立一種在兩者之間共享的加密通道,它可以用來(lái)驗(yàn)證后續(xù)的協(xié)議信息并降低通訊回合數(shù)。在OpenID規(guī)范中對(duì)于實(shí)際創(chuàng)建關(guān)聯(lián)的過(guò)程進(jìn)行了詳盡的描述。簡(jiǎn)單來(lái)講就是使用了一種Diffie-Hellman密鑰交換算法來(lái)生成共享密鑰。此密鑰用于對(duì)信息進(jìn)行簽名。

          這樣使得外部站點(diǎn)和OpenID服務(wù)器之間能夠安全地通訊。這里指的“安全性”是通過(guò)傳輸層(使用SSL)或者通過(guò)應(yīng)用層的HMAC SHA1或者HMAC SHA256算法實(shí)現(xiàn)的。關(guān)聯(lián)請(qǐng)求的成果就是assoc_handle(關(guān)聯(lián)權(quán)柄),外部站點(diǎn)和OpenID服務(wù)器將在本次關(guān)聯(lián)的后繼活動(dòng)中將它作為對(duì)消息進(jìn)行加密的密鑰。

          關(guān)聯(lián)階段被標(biāo)為“可選的”,這是因?yàn)镺penID協(xié)議還允許外部站點(diǎn)直接請(qǐng)求認(rèn)證(不作關(guān)聯(lián))、并且接著請(qǐng)求對(duì)認(rèn)證信息進(jìn)行驗(yàn)證。這樣外部站點(diǎn)可以不保有關(guān)聯(lián)權(quán)柄信息,以實(shí)現(xiàn)無(wú)狀態(tài)通訊。而這種方式被推薦用于執(zhí)行與OpenID服務(wù)器之間的相關(guān)通訊,但如果不能使用此方式的話,就必須創(chuàng)建上面講的關(guān)聯(lián)方式。

          5. Relying Party站點(diǎn)請(qǐng)求認(rèn)證

          我們通過(guò)使用重定向頁(yè)面可以建立認(rèn)證請(qǐng)求。請(qǐng)查看下表中的重要參數(shù)值,詳細(xì)信息請(qǐng)參考OpenID相關(guān)信息格式文檔:
          image
          請(qǐng)注意:外部站點(diǎn)并沒(méi)有直接發(fā)送HTTP請(qǐng)求到OpenID服務(wù)器,而是重定向到OpenID服務(wù)器頁(yè)面。由于這樣使得OpenID服務(wù)器能夠從用戶瀏覽器中讀取cookie而沒(méi)有將任何認(rèn)證細(xì)節(jié)泄露給外部站點(diǎn),因此這個(gè)過(guò)程是安全的。

          6. OpenID服務(wù)器回應(yīng)認(rèn)證請(qǐng)求

          在接收到OpenID認(rèn)證請(qǐng)求后,OpenID服務(wù)器必須決定允許還是拒絕此用戶的認(rèn)證。這將由用戶從前是否在OpenID服務(wù)器上認(rèn)證過(guò)決定。

          請(qǐng)注意:OpenID服務(wù)器在接收認(rèn)證請(qǐng)求信息時(shí)是具有控制權(quán)的。這意味著它不但能夠異步地回應(yīng)認(rèn)證請(qǐng)求信息,并在它回應(yīng)認(rèn)證請(qǐng)求之前與用戶進(jìn)行一系列的交互。大多數(shù)認(rèn)證服務(wù)器都提供給用戶一個(gè)頁(yè)面使其能夠選擇允許或者拒絕來(lái)自外部站點(diǎn)的認(rèn)證請(qǐng)求。

          一旦OpenID服務(wù)器已經(jīng)回應(yīng)了認(rèn)證請(qǐng)求,那么它將創(chuàng)建一個(gè)如下描述的認(rèn)證回應(yīng)信息,低層信息細(xì)節(jié)請(qǐng)閱讀OpenID協(xié)議文檔:
          image

          此回應(yīng)通過(guò)將用戶重定向到外部站點(diǎn)的方式發(fā)送,以確保外部站點(diǎn)和OpenID服務(wù)器之間在認(rèn)證請(qǐng)求/回應(yīng)過(guò)程中沒(méi)有直接通訊。

          7. 驗(yàn)證間接回應(yīng)

          協(xié)議的最后一步是外部站點(diǎn)驗(yàn)證這個(gè)發(fā)自O(shè)penID服務(wù)器的間接認(rèn)證回應(yīng)信息。

          當(dāng)外部站點(diǎn)接收到回應(yīng)時(shí),它必須在接受其內(nèi)容之前進(jìn)行下面的驗(yàn)證:
                  • “openid.return_to”的參數(shù)值是否匹配當(dāng)前請(qǐng)求的URL。這確保OpenID服務(wù)器重定向用戶、發(fā)送回應(yīng)信息到正確的URL。
                  • 被發(fā)現(xiàn)的信息是否與回應(yīng)信息相匹配。
                  • 具有相同參數(shù)值的“openid.response_nonce”表示OpenID服務(wù)器遭到了重放攻擊(reply attacks)。
                  • 在回應(yīng)信息中的簽名是否有效、要求的簽名域是否都被簽名。這保證認(rèn)證信息沒(méi)有被篡改過(guò)。

          協(xié)議擴(kuò)展

          OpenID協(xié)議提供了一個(gè)基本的認(rèn)證機(jī)制。目前還有基于OpenID的其它可用協(xié)議:
                  • Attribute Exchange:OpenID屬性交換是一種用于在端點(diǎn)之間交換標(biāo)識(shí)信息OpenID服務(wù)擴(kuò)展。其提供了對(duì)標(biāo)識(shí)信息的接收和存儲(chǔ)。
                  • Simple Registration:這是OpenID認(rèn)證協(xié)議的擴(kuò)展,它允許非常輕量級(jí)的配置交換。主要用于在終端用戶使用web服務(wù)注冊(cè)新帳號(hào)時(shí)傳送八種常用的請(qǐng)求信息。

          使用OpenID4Java實(shí)現(xiàn)OpenID協(xié)議
          image
          OpenID4Java是對(duì)OpenID1.1和2.0規(guī)范的實(shí)現(xiàn),目前它通過(guò)code.google.com系統(tǒng)進(jìn)行維護(hù)。此項(xiàng)目初始代碼是由Sxip捐獻(xiàn)出來(lái)的,而后Atlassian等公司參與進(jìn)來(lái),并為實(shí)現(xiàn)支持2.0規(guī)范(屬性交換規(guī)范)的API貢獻(xiàn)了大量的工作。

          在使用OpenID4Java之前,你需要完成以下工作:
                  • 下載OpenID4Java代碼庫(kù),并將其安裝到你的項(xiàng)目中。
                  • 修改你的認(rèn)證提示,使其詢問(wèn)用戶的OpenID標(biāo)識(shí),而不是從前的用戶名和密碼。
                  • 創(chuàng)建針對(duì)用戶標(biāo)識(shí)的認(rèn)證請(qǐng)求,并將用戶重定向到他們的OpenID服務(wù)器。
                  • 在返回URL中接收OpenID提供者的認(rèn)證回應(yīng)并進(jìn)行驗(yàn)證。

          這樣,你的web應(yīng)用就會(huì)像在上面協(xié)議綜述中的流程圖所展示的“Relying Party”那樣工作。

          第一步是創(chuàng)建消費(fèi)者對(duì)象,它將向認(rèn)證服務(wù)器發(fā)出認(rèn)證請(qǐng)求。這里我們將消費(fèi)者對(duì)象視為一個(gè)貫穿應(yīng)用的個(gè)體,以使相關(guān)的關(guān)聯(lián)密鑰能夠保存在同一位置。因?yàn)楫?dāng)面臨多個(gè)認(rèn)證請(qǐng)求時(shí),在不同的請(qǐng)求之間保存密鑰將在兩個(gè)端點(diǎn)(請(qǐng)求和回應(yīng)端點(diǎn))間引起下幅度的性能下降。

          Sample Consumer代碼片段:
          /**
          * Sample Consumer (Relying Party) implementation.
          */
          public class SampleConsumer
          {
              public ConsumerManager manager;

              public SampleConsumer() throws ConsumerException
              {
                  // instantiate a ConsumerManager object
                  manager = new ConsumerManager();
              }

              ...
          }


          一旦用戶提供了OpenID URL,你就需要獲取OpenID認(rèn)證服務(wù)器的端點(diǎn)URL,發(fā)送請(qǐng)求到此URL。而OpenID認(rèn)證服務(wù)器的端點(diǎn)被確定后,你還要?jiǎng)?chuàng)建一個(gè)和服務(wù)器關(guān)聯(lián)的共享密鑰。
          // discover the OpenID authentication server's endpoint URL
          List discoveries = manager.discover(userSuppliedOpenID);

          // attempt to associate with the OpenID provider
          // and retrieve one service endpoint for authentication
          DiscoveryInformation discovered = manager.associate(discoveries);

          // store the discovery information in the user's session for later use
          session.setAttribute("discovered", discovered);


          以上的調(diào)用將完成:
                  • 下載OpenID提供者列表(一般只有一個(gè)提供者)。返回結(jié)果將按照用戶指定的優(yōu)選順序排列。
                  • 通過(guò)關(guān)聯(lián)獲取和OpenID提供者之間的共享密鑰。
                  • 將關(guān)聯(lián)(發(fā)現(xiàn)信息)保存,以備之后的使用。

          我們現(xiàn)在需要將用戶重定向到他們的OpenID提供者頁(yè)面,并告訴OpenID提供者外部站點(diǎn)的地址(返回URL,這里就是你的站點(diǎn)),以使OpenID提供者知道在執(zhí)行完認(rèn)證后將用戶發(fā)送到哪里。
          // define the return path
          String returnURL = "http://company.com/openidresponse.jsp";

          // generate an AuthRequest message to be sent to the OpenID provider
          AuthRequest authReq = manager.authenticate(discovered, returnURL);

          // redirect the user to their provider for authentication
          httpResp.sendRedirect(authReq.getDestinationUrl(true));


          上面的代碼將用戶重定向到他們的OpenID提供者,在那里用戶將被詢問(wèn)是否同意和你的站點(diǎn)進(jìn)行認(rèn)證。(請(qǐng)注意:無(wú)論用戶同意“臨時(shí)”授權(quán)給你的web應(yīng)用、還是“總是”或者“不”授權(quán),OpenID提供者都將保存此首選標(biāo)識(shí))。當(dāng)用戶再次訪問(wèn)你的web應(yīng)用時(shí),如果用戶已經(jīng)被OpenID提供者認(rèn)證過(guò)并且在首次認(rèn)證時(shí)選擇了“總是”,那么此用戶將可以訪問(wèn)你的web應(yīng)用,而無(wú)需再次認(rèn)證。

          在認(rèn)證用戶之后,OpenID提供者將用戶重定向到外部站點(diǎn)(由返回URL定義的web應(yīng)用),并發(fā)送認(rèn)證回應(yīng)信息給你的web應(yīng)用,而你的web應(yīng)用將需要接收此回應(yīng)。你可以顯示錯(cuò)誤信息或者將用戶發(fā)送到“成功”頁(yè)面,這完全取決于你的工作流。

          這是處理來(lái)自O(shè)penID提供者認(rèn)證信息的最簡(jiǎn)單過(guò)程:
          // extract the parameters from the authentication response
          // (which comes in as a HTTP request from the OpenID provider)
          ParameterList openidResp = new ParameterList(request.getParameterMap());

          // retrieve the previously stored discovery information
          DiscoveryInformation discovered = (DiscoveryInformation) session.getAttribute("discovered");

          // extract the receiving URL from the HTTP request
          StringBuffer receivingURL = request.getRequestURL();
          String queryString = request.getQueryString();

          if (queryString != null && queryString.length() > 0)
             receivingURL.append("?").append(request.getQueryString());

          // verify the response
          VerificationResult verification = manager.verify(receivingURL.toString(), openidResp, discovered);

          // examine the verification result and extract the verified identifier
          Identifier verified = verification.getVerifiedId();

          if (verified != null)
              // success, use the verified identifier to identify the user
          else
          // OpenID authentication failed


          查看完整的Sample Consumer代碼:http://code.google.com/p/openid4java/wiki/SampleConsumer

          結(jié)論

          OpenID是通過(guò)標(biāo)準(zhǔn)化認(rèn)證方式由互聯(lián)網(wǎng)社區(qū)催生出來(lái)的綜合效應(yīng)。它完成了和SAML這些現(xiàn)存協(xié)議同樣的事情,但它卻易于安裝、部署和維護(hù)。任何具備基本編程技能的人都能夠在其現(xiàn)有或者新建的網(wǎng)站上部署OpenID技術(shù)。

          OpenID已經(jīng)獲得愈加廣泛的使用。我們有理由相信,在不久之后的公司之間、像Google和Yahoo這樣的門戶站點(diǎn)之間都將支持此技術(shù),OpenID技術(shù)將隨著互聯(lián)網(wǎng)社區(qū)的發(fā)展而成為網(wǎng)站之間通用的主流認(rèn)證方法。
          關(guān)于OpenID技術(shù)的更多信息,請(qǐng)?jiān)L問(wèn):http://openid.net/

          原文(《Using OpenID》)作者簡(jiǎn)介

          Justen StepkaAtlassian的Crowd單點(diǎn)登錄安全系統(tǒng)的項(xiàng)目管理者,同時(shí)也是OpenID4Java項(xiàng)目的提交者(committer)。Crowd團(tuán)隊(duì)目前正在開(kāi)發(fā)實(shí)現(xiàn)OpenID2.0規(guī)范的服務(wù)站點(diǎn)。Justen從前是Authentisoft的CEO,該公司于2006年被Atlassian收購(gòu)。

          Shihab Hamid是在Atlassian工作的工程師,他主要負(fù)責(zé)用Crowd產(chǎn)品在OpenID集成方面的設(shè)計(jì)和開(kāi)發(fā)。同時(shí)也是OpenID4Java項(xiàng)目的提交者。

          相關(guān)資料

                  • OpenID官方網(wǎng)站:http://openid.net/
                  • OpenID工作過(guò)程:http://openid.net/about.bml
                  • OpenID4Java項(xiàng)目主頁(yè):http://code.google.com/p/openid4java/wiki/ProjectHome_zh_CN
                  • 下載OpenID4Java:http://code.sxip.com/openid4java/
                  • 支持OpenID的各種代碼庫(kù):http://www.openidenabled.com/
                  • 目前支持OpenID的主要站點(diǎn):http://iwantmyopenid.org/bounty/sponsors
          posted on 2008-11-04 17:53 蘆葦 閱讀(3487) 評(píng)論(2)  編輯  收藏 所屬分類: JAVA其他

          Feedback

          # re: OpenID使用手冊(cè) 2008-11-04 18:28 蘆葦
          關(guān)于OPENID的單點(diǎn)登陸協(xié)議

          因?yàn)榻?jīng)常看到有OpenId的吹捧者,所以本來(lái)希望寫一個(gè)OpenId的BLOG,引起大家的注意,然后從他們哪兒獲得一些關(guān)于OpenId詳細(xì)協(xié)議的資料,可惜失算了。

          不得以,今天早上,花了一些時(shí)間,在詞典的幫助下用我蹩腳的英語(yǔ)翻譯了一下OpenId的協(xié)議。終于搞明白了OpenId的加密驗(yàn)證模式。

          最關(guān)鍵的是第三步和第七步。這兩步由應(yīng)用服務(wù)器任選其一,他們都是應(yīng)用服務(wù)器直接與身份驗(yàn)證服務(wù)器交互,第三步是獲得并保存一個(gè)密匙,用于嚴(yán)整用戶所傳遞的數(shù)據(jù)是否合法。第七步則是直接把接受的信息交個(gè)身份驗(yàn)證服務(wù)器,然后由身份驗(yàn)證服務(wù)器來(lái)驗(yàn)證這個(gè)信息是否合法。

          這樣以來(lái),我前邊所講的哪個(gè)HACK的模式就的確是行不通的了。

          ———以下是我翻譯的全文———

          一個(gè)帶圖片說(shuō)明的OpenId協(xié)議介紹

          A description of the OpenID protocol with diagrams.

           

          1: User submits Identity URL

          1:用戶提交身份地址

          The consumer uses a form with GET or POST to allow the user to enter their OpenID url.

          應(yīng)用服務(wù)器通過(guò)GET或者POST方法獲得用戶提交他們的OpenId地址(身份地址)

          2: Consumer fetches Identity URL

          2:應(yīng)用服務(wù)器取得身份驗(yàn)證服務(wù)器

          The consumer parses the HTML content and looks for a tag:

          <LINK REL='openid.server' HREF=(the server)>

          應(yīng)用服務(wù)器解吸用戶提交的地址的數(shù)據(jù)中的HTML標(biāo)簽:<link rel=’openid.server’ href=’the server’>(其中the server 就是身份驗(yàn)證服務(wù)器)

          3: Consumer associates with server (option 1)

          3:應(yīng)用服務(wù)器與身份驗(yàn)證服務(wù)器交互(選項(xiàng)1

          In order to communicate securely with the server, the consumer gets an association with the server discovered in step 2, using an existing association if it is available, otherwise visiting the server and using Diffie Hellman to negotiate a shared secret with which to sign communication.  A consumer unable to store state uses "dumb mode" which does not perform this step, and instead uses step 7.

          為了能夠與身份驗(yàn)證服務(wù)器安全的通信,應(yīng)用服務(wù)器需要向(從第2步獲取的)身份驗(yàn)證服務(wù)器請(qǐng)求一個(gè)協(xié)議。如果有現(xiàn)成的可以使用的協(xié)議,則用現(xiàn)有的協(xié)議,否則,通過(guò)Diffie Hellman的方法獲得一個(gè)共享密匙,靜默模式(dumb mode)下的應(yīng)用服務(wù)器不需要這一步,而是使用第7步的操作。

          4: Consumer redirects the user to the server

          4:應(yīng)用服務(wù)器將用戶重定向到身份驗(yàn)證服務(wù)器

          The OpenID server URL accepts a query, containing all the information the server needs to check the user's identity and redirect the user back to the consumer.  The server checks the authentication of the user.  If the user is signed in (has an auth cookie) and has already authorized sending their identity to the consumer, step 5 may be skipped.

          OpenId服務(wù)器接受一個(gè)包含所有應(yīng)用服務(wù)器需要用來(lái)驗(yàn)證用戶的信息,如果用戶已經(jīng)登陸(有COOKIE)并且他已經(jīng)同意發(fā)送他的身份信息給應(yīng)用服務(wù)器的話,第5步可以跳過(guò)。

          5: User Authenticates to server

          5:用戶鑒別是否是自己訪問(wèn)的服務(wù)

          The user authenticates to the server with a cookie or a username and password, and the server asks the user for permission to send their identity information to the consumer.

          通過(guò)COOKIE或者用戶名+密碼驗(yàn)證當(dāng)前用戶是否登陸,并且詢問(wèn)當(dāng)前用戶是否允許應(yīng)用服務(wù)器獲得自己的身份信息。

          6: Server redirects the user back to the consumer

          6: 身份驗(yàn)證服務(wù)器重定向用戶到應(yīng)用服務(wù)器

          The consumer parses the servers response (which is appended to the return-to URL the consumer sent) and verifies it using the association, or in the case of dumb mode proceeds to step 7.

          應(yīng)用服務(wù)器使用獲得的身份驗(yàn)證服務(wù)器的協(xié)議,校驗(yàn)并解析所返回的數(shù)據(jù)。如果在靜默模式(dumb mode)下,繼續(xù)第7步。

          7: Consumer verifies the response with the server (option 2)

          7:應(yīng)用服務(wù)器通過(guò)身份驗(yàn)證服務(wù)器校驗(yàn)接收到的信息(選項(xiàng)2

          Communicating directly with the server, the dumb mode consumer checks the response received via the User Agent in the redirect.

          應(yīng)用服務(wù)器直接連接身份驗(yàn)證服務(wù)器校驗(yàn)接受到的信息,在靜默模式下的應(yīng)用服務(wù)器使用重定向的方法通過(guò)身份地址(User Agent)核對(duì)接受到的信息。



          Trackback: http://tb.donews.net/TrackBack.aspx?PostId=1085110

            回復(fù)  更多評(píng)論
            

          # re: OpenID使用手冊(cè) 2008-11-04 18:38 蘆葦
          openid server
          http://code.google.com/p/openid-server/
          http://www.movabletype.org/download.html
          客戶端插件:

          http://openid4java.googlecode.com/svn/trunk
            回復(fù)  更多評(píng)論
            

          主站蜘蛛池模板: 商水县| 英超| 乐陵市| 平安县| 莱西市| SHOW| 通城县| 新巴尔虎左旗| 江达县| 铁岭市| 兴城市| 博爱县| 岑巩县| 通山县| 昌黎县| 横山县| 康马县| 虞城县| 阳西县| 湖州市| 克山县| 江城| 会泽县| 舞钢市| 溧阳市| 九龙城区| 宜君县| 三门县| 温泉县| 新乡县| 日喀则市| 辉南县| 湄潭县| 岳普湖县| 淄博市| 龙口市| 宝兴县| 丘北县| 新源县| 石嘴山市| 皮山县|