<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    空間站

    北極心空

      BlogJava :: 首頁 :: 聯系 :: 聚合  :: 管理
      15 Posts :: 393 Stories :: 160 Comments :: 0 Trackbacks

    摘要:

    OpenID是一種開放、離散式的用于用戶數字標識的開源框架。在網絡應用日益充斥的今天,作為終端用戶的我們不得不在每個網站上設置帳號,并管理眾多的帳號。而采用OpenID技術的話,你就無須再管理這些相互獨立的帳號,而是通過認證服務器管理自己唯一的身份標識。本文將詳細解釋OpenID技術框架以及如何使用Java進行開發。


     

    OpenID使用手冊

    作者:cleverpig
    image


    什么是OpenID?

    OpenID是一種開放、離散式的用于用戶數字標識的開源框架。

    請讓我們思考自己所擁有的在線帳號種類:博客、wiki、to-do list、個人相冊。在網絡應用日益充斥的今天,這些個人在線帳號可謂不勝枚舉,而對帳號的需要也同樣無處不在,乃至當我們想在好友博客上進行評論時都需要注冊成為該博客系統的用戶。于是作為終端用戶,我們不得不在每個網站上設置帳號,并管理眾多的帳號。而采用OpenID技術的話,你就無須再管理這些相互獨立的帳號,而是通過認證服務器管理自己唯一的身份標識。

    OpenID常見的應用場景:某用戶試圖登錄一個外部網站。與提交用戶名和密碼的方式不同,他只提交了屬于自己的一個URL,例如:http://johnsmith.example.com/

    這個URL即指向了用戶的OpenID認證服務器,同時又是用戶的身份標識。因此外部網站使用此URL便可以找到用戶的認證服務器,并詢問認證服務器:“該用戶聲稱他擁有此URL。而這個URL說明了你負責認證工作,那么請告訴我,該用戶能否訪問我的站點?”。認證服務器將提示用戶登入認證系統,并詢問用戶是否允許和外部網站進行認證。如果用戶同意的話,那么認證服務器將通知外部網站——用戶已經通過認證。在上面,我們通過擬人化的表達方式來形象生動地詮釋整個認證請求/回應過程。

    用戶可以使用同一個URL用作在任何支持OpenID認證的外部網站中使用的標識。這正是OpenID與其它傳統認證方式的最大不同。通過使用URL,可以使外部站點非常容易地獲取到負責認證工作的服務器位置。而只有認證服務器才需要輸入密碼來驗證用戶身份。其它希望驗證用戶身份的站點都將詢問用戶所注冊的認證服務器。如果你正在使用支持OpenID的門戶站點(比如AOL),那么你就可以使用現成的AOL即時消息登錄帳號來登錄AOL站點,而無需另外注冊。因此,我們可以猜想Google和Yahoo也許已經開始著手建造他們的OpenID服務。

    你一定想知道OpenID是如何實現分散化服務的?由于用戶具有選擇OpenID服務提供者的權利,因此你會在最初選擇AOL作為OpenID提供者,而過一段時間后,可能覺得希望更換到另外一個OpenID提供者,此時你所需要做的就是修改以下的HTML標簽:
    <link rel="openid.server" >

    保存這些link元數據的最常見位置就是個人站點(比如博客)的根頁面。

    如何使用OpenID?

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

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

    哪些網站支持OpenID?

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

    下面是實現了OpenID代碼庫的語言列表:
            • C#
            • C++
            • Java
            • Perl
            • Python
            • Ruby
            • PHP
            • Coldfusion

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

    OpenID協議綜述

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

    用戶登入外部站點的過程主要分為以下七個步驟:

    1. Relying Party站點請求用戶標識

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

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

    用戶標識類似這個樣子:http://myname.myhost.com/。外部站點經常將OpenID logo放置到其登錄form上,這樣可以使你很快地辨別出是否使用OpenID。
    image
    用戶在點擊位于外部站點登錄頁面上的“Login”按鈕后便啟動了認證過程。

    2.“標準化”: Relying Party站點整理用戶標識

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

    下面是一些示例:
    image

    下面的流程圖描繪了標準化處理過程:
    image

    3.“發現”: Relying Party站點查詢與OpenID服務器進行通訊的方式

    外部站點使用標準化的標識來查詢用于發起請求所必須的信息。對于“發現”階段來講,其使用的解析協議和獲取的結果文檔都取決于在標準化階段決定的標識類型。這正是OpenID2.0規范的特殊之處。
    image

    快速參考:

            • XRI 解析:類似通過UDP將主機名解析為IP的DNS協議;它將XRI轉換為XRDS。其目的是提供一種將厚重、通用的XRI格式轉換為真實可用的描述符。

            • YADIS協議:將URL連接到XRDS上。這是一種非常簡單的協議,它將當前的HTTP或者HTTPS URL直接指向XRDS。

            • XRDS:一種基于XML的XRI資源描述符。它被設計用來提供關于XRI的可用的、描述性信息。在OpenID應用場合中,XRDS用來描述OpenID服務器,并且使用“priority”參數標識了用戶對服務器的優選順序。在下面的示例中,http://www.livejournal.com/users/frank具有最高的優先權(最低的數值):
    <?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>部分必須提供以下標簽:
    <link rel="openid2.provider" />


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


    例如,某人正在使用openidprovider.com這個OpenID服務器來驗證他在另一個OpenID服務器usersite.com上的身份,那么其本地標識將使用類似user.openidprovider.com的形式。

    這個“發現”的過程允許外部站點知道兩件事,其中一件是外部站點如何與OpenID服務器進行通訊:
            1.OpenID提供者端點URL:OpenID提供者的最終URL(服務器URL)。
            2.認證協議版本: OpenID認證使用的協議版本。

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

    例如,用戶使用http://www.example.com/作為其標識,但外部網站實際上通過https://www.exampleprovider.com/endpoint/這個OpenID服務器來驗證用戶標識https://exampleuser.exampleprovider.com/。那么在對http://www.example.com/執行發現的過程中,我們需要在XRDS文檔的最后一個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站點建立與OpenID服務器之間的關聯(可選)

    通過在外部站點和OpenID服務器之間的關聯(association),我們可以建立一種在兩者之間共享的加密通道,它可以用來驗證后續的協議信息并降低通訊回合數。在OpenID規范中對于實際創建關聯的過程進行了詳盡的描述。簡單來講就是使用了一種Diffie-Hellman密鑰交換算法來生成共享密鑰。此密鑰用于對信息進行簽名。

    這樣使得外部站點和OpenID服務器之間能夠安全地通訊。這里指的“安全性”是通過傳輸層(使用SSL)或者通過應用層的HMAC SHA1或者HMAC SHA256算法實現的。關聯請求的成果就是assoc_handle(關聯權柄),外部站點和OpenID服務器將在本次關聯的后繼活動中將它作為對消息進行加密的密鑰。

    關聯階段被標為“可選的”,這是因為OpenID協議還允許外部站點直接請求認證(不作關聯)、并且接著請求對認證信息進行驗證。這樣外部站點可以不保有關聯權柄信息,以實現無狀態通訊。而這種方式被推薦用于執行與OpenID服務器之間的相關通訊,但如果不能使用此方式的話,就必須創建上面講的關聯方式。

    5. Relying Party站點請求認證

    我們通過使用重定向頁面可以建立認證請求。請查看下表中的重要參數值,詳細信息請參考OpenID相關信息格式文檔:
    image
    請注意:外部站點并沒有直接發送HTTP請求到OpenID服務器,而是重定向到OpenID服務器頁面。由于這樣使得OpenID服務器能夠從用戶瀏覽器中讀取cookie而沒有將任何認證細節泄露給外部站點,因此這個過程是安全的。

    6. OpenID服務器回應認證請求

    在接收到OpenID認證請求后,OpenID服務器必須決定允許還是拒絕此用戶的認證。這將由用戶從前是否在OpenID服務器上認證過決定。

    請注意:OpenID服務器在接收認證請求信息時是具有控制權的。這意味著它不但能夠異步地回應認證請求信息,并在它回應認證請求之前與用戶進行一系列的交互。大多數認證服務器都提供給用戶一個頁面使其能夠選擇允許或者拒絕來自外部站點的認證請求。

    一旦OpenID服務器已經回應了認證請求,那么它將創建一個如下描述的認證回應信息,低層信息細節請閱讀OpenID協議文檔:
    image

    此回應通過將用戶重定向到外部站點的方式發送,以確保外部站點和OpenID服務器之間在認證請求/回應過程中沒有直接通訊。

    7. 驗證間接回應

    協議的最后一步是外部站點驗證這個發自OpenID服務器的間接認證回應信息。

    當外部站點接收到回應時,它必須在接受其內容之前進行下面的驗證:
            • “openid.return_to”的參數值是否匹配當前請求的URL。這確保OpenID服務器重定向用戶、發送回應信息到正確的URL。
            • 被發現的信息是否與回應信息相匹配。
            • 具有相同參數值的“openid.response_nonce”表示OpenID服務器遭到了重放攻擊(reply attacks)。
            • 在回應信息中的簽名是否有效、要求的簽名域是否都被簽名。這保證認證信息沒有被篡改過。

    協議擴展

    OpenID協議提供了一個基本的認證機制。目前還有基于OpenID的其它可用協議:
            • Attribute Exchange:OpenID屬性交換是一種用于在端點之間交換標識信息OpenID服務擴展。其提供了對標識信息的接收和存儲。
            • Simple Registration:這是OpenID認證協議的擴展,它允許非常輕量級的配置交換。主要用于在終端用戶使用web服務注冊新帳號時傳送八種常用的請求信息。

    使用OpenID4Java實現OpenID協議
    image
    OpenID4Java是對OpenID1.1和2.0規范的實現,目前它通過code.google.com系統進行維護。此項目初始代碼是由Sxip捐獻出來的,而后Atlassian等公司參與進來,并為實現支持2.0規范(屬性交換規范)的API貢獻了大量的工作。

    在使用OpenID4Java之前,你需要完成以下工作:
            • 下載OpenID4Java代碼庫,并將其安裝到你的項目中。
            • 修改你的認證提示,使其詢問用戶的OpenID標識,而不是從前的用戶名和密碼。
            • 創建針對用戶標識的認證請求,并將用戶重定向到他們的OpenID服務器。
            • 在返回URL中接收OpenID提供者的認證回應并進行驗證。

    這樣,你的web應用就會像在上面協議綜述中的流程圖所展示的“Relying Party”那樣工作。

    第一步是創建消費者對象,它將向認證服務器發出認證請求。這里我們將消費者對象視為一個貫穿應用的個體,以使相關的關聯密鑰能夠保存在同一位置。因為當面臨多個認證請求時,在不同的請求之間保存密鑰將在兩個端點(請求和回應端點)間引起下幅度的性能下降。

    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認證服務器的端點URL,發送請求到此URL。而OpenID認證服務器的端點被確定后,你還要創建一個和服務器關聯的共享密鑰。
    // 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);


    以上的調用將完成:
            • 下載OpenID提供者列表(一般只有一個提供者)。返回結果將按照用戶指定的優選順序排列。
            • 通過關聯獲取和OpenID提供者之間的共享密鑰。
            • 將關聯(發現信息)保存,以備之后的使用。

    我們現在需要將用戶重定向到他們的OpenID提供者頁面,并告訴OpenID提供者外部站點的地址(返回URL,這里就是你的站點),以使OpenID提供者知道在執行完認證后將用戶發送到哪里。
    // 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提供者,在那里用戶將被詢問是否同意和你的站點進行認證。(請注意:無論用戶同意“臨時”授權給你的web應用、還是“總是”或者“不”授權,OpenID提供者都將保存此首選標識)。當用戶再次訪問你的web應用時,如果用戶已經被OpenID提供者認證過并且在首次認證時選擇了“總是”,那么此用戶將可以訪問你的web應用,而無需再次認證。

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

    這是處理來自OpenID提供者認證信息的最簡單過程:
    // 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

    結論

    OpenID是通過標準化認證方式由互聯網社區催生出來的綜合效應。它完成了和SAML這些現存協議同樣的事情,但它卻易于安裝、部署和維護。任何具備基本編程技能的人都能夠在其現有或者新建的網站上部署OpenID技術。

    OpenID已經獲得愈加廣泛的使用。我們有理由相信,在不久之后的公司之間、像Google和Yahoo這樣的門戶站點之間都將支持此技術,OpenID技術將隨著互聯網社區的發展而成為網站之間通用的主流認證方法。
    關于OpenID技術的更多信息,請訪問:http://openid.net/

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

    Justen StepkaAtlassian的Crowd單點登錄安全系統的項目管理者,同時也是OpenID4Java項目的提交者(committer)。Crowd團隊目前正在開發實現OpenID2.0規范的服務站點。Justen從前是Authentisoft的CEO,該公司于2006年被Atlassian收購。

    Shihab Hamid是在Atlassian工作的工程師,他主要負責用Crowd產品在OpenID集成方面的設計和開發。同時也是OpenID4Java項目的提交者。

    相關資料

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

    Feedback

    # re: OpenID使用手冊 2008-11-04 18:28 蘆葦
    關于OPENID的單點登陸協議

    因為經常看到有OpenId的吹捧者,所以本來希望寫一個OpenId的BLOG,引起大家的注意,然后從他們哪兒獲得一些關于OpenId詳細協議的資料,可惜失算了。

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

    最關鍵的是第三步和第七步。這兩步由應用服務器任選其一,他們都是應用服務器直接與身份驗證服務器交互,第三步是獲得并保存一個密匙,用于嚴整用戶所傳遞的數據是否合法。第七步則是直接把接受的信息交個身份驗證服務器,然后由身份驗證服務器來驗證這個信息是否合法。

    這樣以來,我前邊所講的哪個HACK的模式就的確是行不通的了。

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

    一個帶圖片說明的OpenId協議介紹

    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.

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

    2: Consumer fetches Identity URL

    2:應用服務器取得身份驗證服務器

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

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

    應用服務器解吸用戶提交的地址的數據中的HTML標簽:<link rel=’openid.server’ href=’the server’>(其中the server 就是身份驗證服務器)

    3: Consumer associates with server (option 1)

    3:應用服務器與身份驗證服務器交互(選項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.

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

    4: Consumer redirects the user to the server

    4:應用服務器將用戶重定向到身份驗證服務器

    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服務器接受一個包含所有應用服務器需要用來驗證用戶的信息,如果用戶已經登陸(有COOKIE)并且他已經同意發送他的身份信息給應用服務器的話,第5步可以跳過。

    5: User Authenticates to server

    5:用戶鑒別是否是自己訪問的服務

    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.

    通過COOKIE或者用戶名+密碼驗證當前用戶是否登陸,并且詢問當前用戶是否允許應用服務器獲得自己的身份信息。

    6: Server redirects the user back to the consumer

    6: 身份驗證服務器重定向用戶到應用服務器

    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.

    應用服務器使用獲得的身份驗證服務器的協議,校驗并解析所返回的數據。如果在靜默模式(dumb mode)下,繼續第7步。

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

    7:應用服務器通過身份驗證服務器校驗接收到的信息(選項2

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

    應用服務器直接連接身份驗證服務器校驗接受到的信息,在靜默模式下的應用服務器使用重定向的方法通過身份地址(User Agent)核對接受到的信息。



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

      回復  更多評論
      

    # re: OpenID使用手冊 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
      回復  更多評論
      

    主站蜘蛛池模板: 亚洲免费视频播放| 亚欧洲精品在线视频免费观看 | 69式互添免费视频| 亚洲日韩精品国产3区| 可以免费看黄的网站| 精品国产日韩亚洲一区在线| jizz免费在线影视观看网站| 亚洲国产精品lv| 日韩高清在线免费看| 亚洲一日韩欧美中文字幕在线| 3344永久在线观看视频免费首页| 亚洲AV乱码一区二区三区林ゆな| 日韩电影免费在线观看网站| 亚洲乱码中文字幕久久孕妇黑人| 亚洲阿v天堂在线| 久久国产福利免费| 亚洲资源最新版在线观看| 国产成人福利免费视频| 菠萝菠萝蜜在线免费视频| 亚洲Av无码国产情品久久| 666精品国产精品亚洲| 免费人成在线观看播放a| 亚洲第一永久AV网站久久精品男人的天堂AV| 亚洲熟妇自偷自拍另欧美| 亚洲精品国产字幕久久不卡| 成年女人免费视频播放77777 | 菠萝菠萝蜜在线免费视频| 亚洲毛片一级带毛片基地| 亚洲熟女一区二区三区| 无码日韩精品一区二区三区免费| 日韩一区二区免费视频| 久久久久国产精品免费网站| 久久精品九九亚洲精品| mm1313亚洲精品无码又大又粗| 久久久久亚洲av无码专区导航 | 青娱乐免费视频在线观看| 精品亚洲AV无码一区二区| 337p日本欧洲亚洲大胆裸体艺术| 最近中文字幕大全免费版在线| 91亚洲国产成人精品下载| 亚洲一区二区三区自拍公司|