hdknr.com's profilehdknrinthespacePhotosBlogLists Tools Help

hdknrinthespace

by hdknr.com

Log

July 03

django: HTTPリクエストをダンプする。

def dump_openid_request(request):
    d = normalDict( request.POST or request.GET )
    d.update( normalDict(request.META) )
    k=d.keys()
    k.sort( lambda x, y : cmp(x,y) )
    for x in k:
        print "OpenID Request : %s \t\t%s" % ( x , d[x])

OpenID 2.0 : Verifying Signatures (署名検証)

http://openid.net/specs/openid-authentication-2_0.html#verifying_signatures

11.4.  Verifying Signatures (署名検証)

If the Relying Party has stored an association with the association handle specified in the assertion, it MUST check the signature on the assertion itself. If it does not have an association stored, it MUST request that the OP verify the signature via Direct Verification (Verifying Directly with the OpenID Provider).

RPがアサーションにしめされたアソシエーションハンドルのアソシエーションを保存しているのであれば、アサーションのシグネチャをそれで検証しなければなりません。もしも、アサーションががなければ直接検証によってOPにシグネチャを検証するようにリクエストする必要があります。


TOC

11.4.1.  Verifying with an Association (アソシエーションの検証:OP)

The Relying Party follows the same procedure that the OP followed in generating the signature (Generating Signatures), and then compares the signature in the response to the signature it generated. If the signatures do not match, the assertion is invalid.

RPは署名生成の手順と同じ手順にしたがって署名検証をします。署名が一致しなければアサーションは不正です。

If an authentication request included an association handle for an association between the OP and the Relying party, and the OP no longer wishes to use that handle (because it has expired or the secret has been compromised, for instance), the OP will send a response that must be verified directly with the OP, as specified in Section 11.4.2 (Verifying Directly with the OpenID Provider). In that instance, the OP will include the field "openid.invalidate_handle" set to the association handle that the Relying Party included with the original request.

認証要求がOPとRPのアソシーエションのハンドルを含んでいるのであれば、OPはそのハンドルを使いません。OPは応答を直接OPで検証するように返します。openid.invalidate_handleにRPがリクエストに入れたアソシエーションハンドルをセットするのです。


TOC

11.4.2.  Verifying Directly with the OpenID Provider(OPに直接検証する:RP)

To have the signature verification performed by the OP, the Relying Party sends a direct request (Direct Request) to the OP. To verify the signature, the OP uses a private association that was generated when it issued the positive assertion (Positive Assertions).

署名検証をOPにやってもらうためにはダイレクトリクエストを行います。署名を検証するために、OPは先に返答したポジティブ・アサーションに使ったプライベートアソシエーションを使います。


TOC

11.4.2.1.  Request Parameters
  • openid.mode

    Value: "check_authentication"

  • Exact copies of all fields from the authentication response, except for "openid.mode". (openid.mode以外のすべての認証応答のフィールドをコピーして指定します)

For verifying signatures an OP MUST only use private associations and MUST NOT use associations that have shared keys. If the verification request contains a handle for a shared association, it means the Relying Party no longer knows the shared secret, or an entity other than the RP (e.g. an attacker) has established this association with the OP.

OPはプライベートアソシエーションのみを使います。共有キーのあるアソシエーションを使ってはいけません。検証リクストが共有アソシエーションハンドルを含んでいるのであれば、それはRPが共有シークレットを知らないあ、あるいはRP以外(攻撃者)がOPにアソシーエションを確立しようとしているということになります。

To prevent replay attacks, the OP MUST NOT issue more than one verification response for each authentication response it had previously issued. An authentication response and its matching verification request may be identified by their "openid.response_nonce" values.

リプレー攻撃を防ぐために、OPは返答した認証応答ごとに1回だけしか検証応答を返答してはいけません。認証応答と対応する検証応答は”openid.response_nonce”で識別できます。


TOC

11.4.2.2.  Response Parameters
  • ns

    As specified in Section 5.1.2 (Direct Response).

  • is_valid

    Value: "true" or "false"; asserts whether the signature of the verification request is valid.

  • invalidate_handle

    Value: (optional) The "invalidate_handle" value sent in the verification request, if the OP confirms it is invalid.  (OPが無効にしたいハンドル)

    Description: If present in a verification response with "is_valid" set to "true", the Relying Party SHOULD remove the corresponding association from its store and SHOULD NOT send further authentication requests with this handle.  (is_valid=trueの応答であれば、RPは対応するアソシエーションを削除してこのハンドルを使った認証リクエストを二度と行わないこと)

    Note: This two-step process for invalidating associations is necessary to prevent an attacker from invalidating an association at will by adding "invalidate_handle" parameters to an authentication response. (二段階プロセスでアソシエーションを無効にするのは攻撃者が無効にする攻撃から防ぐため) 

July 01

OpenID Plugin for Wordpress : RP Discoveryがサポートされていない。

WS000017

http://hdknr.ubu/blog/openid/ でXRDをサポートしていないから、らしいです。(@kthrtty)

出力しているテンプレートを見る。

hdknr@LennyOne:~/python-openid-2.2.4/examples/djopenid$ vi templates/server/trust.html

{% ifequal trust_root_valid "DISCOVERY_FAILED" %}
  <p>The site <tt>{{ trust_root|escape }}</tt> has requested verification
  of your OpenID.  However, <tt>{{ trust_root|escape }}</tt> does not
  implement OpenID 2.0's relying party verification mechanism.  Please use
  extra caution in deciding whether to release information to this party,
  and ask <tt>{{ trust_root|escape }}</tt> to implement relying party
  verification for your future transactions.</p>

  {% include "server/pape_request_info.html" %}
{% endifequal %}

対応するヴューの処理

hdknr@LennyOne:~/python-openid-2.2.4/examples/djopenid$ vi server/views.py

from openid.server.trustroot import verifyReturnTo

def showDecidePage(request, openid_request):
    """
    Render a page to the user so a trust decision can be made.

    @type openid_request: openid.server.server.CheckIDRequest
    """
    trust_root = openid_request.trust_root    #### RELM
    return_to = openid_request.return_to      #### RETURN_TO

    try:
        # Stringify because template's ifequal can only compare to strings.
        trust_root_valid = verifyReturnTo(trust_root, return_to) \
                           and "Valid" or "Invalid"
    except DiscoveryFailure, err:
        trust_root_valid = "DISCOVERY_FAILED"

    except HTTPFetchingError, err:
        trust_root_valid = "Unreachable"

    pape_request = pape.Request.fromOpenIDRequest(openid_request)

    return direct_to_template(
        request,
        'server/trust.html',
        {'trust_root': trust_root,
         'trust_handler_url':getViewURL(request, processTrustResult),
         'trust_root_valid': trust_root_valid,
         'pape_request': pape_request,

実際は次のように呼び出し。

verifyReturnTo(http://hdknr.ubu/blog/openid/,
http://hdknr.ubu/blog/openid/?openid=consumer&janrain_nonce=2009-07-01T07%3A40%3A59Z9ns9Iw&openid1_claimed_id=http%3A%2F%

2Fhdknr.deb%2Fserver%2Fuser%2F)

_vrfyでDiscoveryFailureが発生。

def verifyReturnTo(realm_str, return_to, _vrfy=getAllowedReturnURLs):
    """Verify that a return_to URL is valid for the given realm.

    This function builds a discovery URL, performs Yadis discovery on
    it, makes sure that the URL does not redirect, parses out the
    return_to URLs, and finally checks to see if the current return_to
    URL matches the return_to.

    @raises DiscoveryFailure: When Yadis discovery fails
    @returns: True if the return_to URL is valid for the realm

    @since: 2.1.0
    """
    realm = TrustRoot.parse(realm_str)

    if realm is None:
        # The realm does not parse as a URL pattern
        return False

    try:
        allowable_urls = _vrfy(realm.buildDiscoveryURL())
    except RealmVerificationRedirected, err:
        oidutil.log(str(err))
        return False

    if returnToMatches(allowable_urls, return_to):
        return True
    else:
        oidutil.log("Failed to validate return_to %r for realm %r, was not "
                    "in %s" % (return_to, realm_str, allowable_urls))
        return False

デフォルトでは、_vrfyがgetAllowedReturnURLs関数。

from openid.yadis import services

def getAllowedReturnURLs(relying_party_url):
    (rp_url_after_redirects, return_to_urls) = services.getServiceEndpoints(
        relying_party_url, _extractReturnURL)    #ここでだめな模様。

    if rp_url_after_redirects != relying_party_url:
        # Verification caused a redirect
        raise RealmVerificationRedirected(
            relying_party_url, rp_url_after_redirects)

    return return_to_urls

yadis/service.py

def getServiceEndpoints(input_url, flt=None):
    result = discover(input_url)
    try:
        endpoints = applyFilter(result.normalized_uri,
                                result.response_text, flt)
    except XRDSError, err:
        raise DiscoveryFailure(str(err), None)
    return (result.normalized_uri, endpoints)

def applyFilter(normalized_uri, xrd_data, flt=None):
    flt = mkFilter(flt)
    et = parseXRDS(xrd_data)                              #<----- ここで例外。
    endpoints = []
    for service_element in iterServices(et):
        endpoints.extend(
            flt.getServiceEndpoints(normalized_uri, service_element))

    return endpoints

yadis/etxrd.py どうやらtext(xrd_data)がElementTreeでXMLにパースできないもよう。
なぜならばWordPressのトップページがHTMLだから。

def parseXRDS(text):
    """Parse the given text as an XRDS document.

    @return: ElementTree containing an XRDS document

    @raises XRDSError: When there is a parse error or the document does
        not contain an XRDS.
    """
    try:
        element = ElementTree.XML(text)
    except XMLError, why:
        exc = XRDSError('Error parsing document as XML') #<--------- ここ
        exc.reason = why
        raise exc
    else:
        tree = ElementTree.ElementTree(element)
        if not isXRDS(tree):
            raise XRDSError('Not an XRDS document')

        return tree

ということです。

WordPressでリクエストヘッダーを見てみると。 ( index.php にデバックコードを入れる)
root@ubuntu-vbox:/home/sites/hdknr.ubu/wordpress_blog_openid# !ta
tail -f /var/log/messages

Jul  1 17:40:40 ubuntu-vbox OpenID[9446]: APACHE REQUEST HEADER:Accept-Encoding:identity
Jul  1 17:40:40 ubuntu-vbox OpenID[9446]: APACHE REQUEST HEADER:Host:hdknr.ubu
Jul  1 17:40:40 ubuntu-vbox OpenID[9446]: APACHE REQUEST HEADER:Connection:close
Jul  1 17:40:40 ubuntu-vbox OpenID[9446]: APACHE REQUEST HEADER:Accept:text/html; q=0.3, application/xhtml+xml; q=0.5, application/xrds+xml
Jul  1 17:40:40 ubuntu-vbox OpenID[9446]: APACHE REQUEST HEADER:User-Agent:python-openid/2.2.1 (linux2) Python-urllib/2.5

ですので、Acceptにapplication/xrds+xmlがしていされたら、WordPressのトップページでXRDSをダウンロードするようにすれば対応可能でしょう。

PHP: Apacheのリクエストヘッダーをログに書いてしらべる

PHPのスクリプトに、次のコードをいれて、tail –f /var/log/messageとかする。

<?php
openlog("OpenID", LOG_PID | LOG_PERROR, LOG_LOCAL0);
$headers = apache_request_headers();
foreach ($headers as $header => $value) {
    syslog(LOG_WARNING, "APACHE REQUEST HEADER:$header:$value");
}
?>

こんな感じ。

root@ubuntu-vbox:/home/sites/hdknr.ubu/wordpress_blog_openid# tail -f /var/log/messages
Jul  1 17:39:49 ubuntu-vbox OpenID[9441]: APACHE REQUEST HEADER:Accept:application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5
Jul  1 17:39:49 ubuntu-vbox OpenID[9441]: APACHE REQUEST HEADER:Accept-Encoding:gzip,deflate,bzip2,sdch
Jul  1 17:39:49 ubuntu-vbox OpenID[9441]: APACHE REQUEST HEADER:Cookie:wp-settings-time-2=1246429625; wp-settings-time-1=1246430028; wp-settings-3=m0%3Do%26m1%3Dc; wp-settings-time-3=1246431930; wordpress_test_cookie=WP+Cookie+check; PHPSESSID=3ff365d0b895a47cae06f5add597b903
Jul  1 17:39:49 ubuntu-vbox OpenID[9441]: APACHE REQUEST HEADER:Accept-Language:ja,en-US;q=0.8,en;q=0.6
Jul  1 17:39:49 ubuntu-vbox OpenID[9441]: APACHE REQUEST HEADER:Accept-Charset:Shift_JIS,utf-8;q=0.7,*;q=0.3
Jul  1 17:40:40 ubuntu-vbox OpenID[9446]: APACHE REQUEST HEADER:Accept-Encoding:identity
Jul  1 17:40:40 ubuntu-vbox OpenID[9446]: APACHE REQUEST HEADER:Host:hdknr.ubu
Jul  1 17:40:40 ubuntu-vbox OpenID[9446]: APACHE REQUEST HEADER:Connection:close
Jul  1 17:40:40 ubuntu-vbox OpenID[9446]: APACHE REQUEST HEADER:Accept:text/html; q=0.3, application/xhtml+xml; q=0.5, application/xrds+xml
Jul  1 17:40:40 ubuntu-vbox OpenID[9446]: APACHE REQUEST HEADER:User-Agent:python-openid/2.2.1 (linux2) Python-urllib/2.5

Wordpress: OpenID Plugin

なんどもやってる気がするが。。。。

root@ubuntu-vbox:/home/sites/hdknr.ubu/wordpress_blog_openid/wp-content# cd plugins/
root@ubuntu-vbox:/home/sites/hdknr.ubu/wordpress_blog_openid/wp-content/plugins# ls -al
合計 24
drwxr-xr-x 4 www-data www-data 4096 2009-06-12 11:35 .
drwxr-xr-x 5 www-data www-data 4096 2009-06-12 11:35 ..
drwxr-xr-x 2 www-data www-data 4096 2009-06-12 11:35 akismet
-rw-r--r-- 1 www-data www-data 2255 2009-06-12 11:35 hello.php
-rw-r--r-- 1 www-data www-data   30 2009-06-12 11:35 index.php
drwxr-xr-x 3 www-data www-data 4096 2009-06-12 11:35 wp-multibyte-patch
root@ubuntu-vbox:/home/sites/hdknr.ubu/wordpress_blog_openid/wp-content/plugins# wget http://downloads.wordpress.org/plugin/openid.3.2.2.zip
--15:11:53--  http://downloads.wordpress.org/plugin/openid.3.2.2.zip
           => `openid.3.2.2.zip'
downloads.wordpress.org をDNSに問いあわせています... 72.233.56.138, 72.233.56.139
downloads.wordpress.org|72.233.56.138|:80 に接続しています... 接続しました。
HTTP による接続要求を送信しました、応答を待っています... 200 OK
長さ: 特定できません [application/octet-stream]
    [                        <=>                                                                                                                                                                ] 536,074      121.19K/s
15:12:01 (85.60 KB/s) - `openid.3.2.2.zip' を保存しました [536074]

root@ubuntu-vbox:/home/sites/hdknr.ubu/wordpress_blog_openid/wp-content/plugins# unzip openid.3.2.2.zip

root@ubuntu-vbox:/home/sites/hdknr.ubu/wordpress_blog_openid/wp-content/plugins# chown -R www-data:www-data openid

このあとWordPressの管理画面でプラグインを有効化する。

adminでwp-adminにログインして、OpenIDを使うテストユーザーを作成。

WS000002 

テストユーザーでログインしなおす。

WS000003

Your OpenID

WS000004

OpenID を指定し、”Add OpenID"

WS000005

OPにAuth Request

WS000006

Possitive Assertionを受けてOpenIDが追加された。

WS000007

ログオフしてOpenIDでログインしてみる。

WS000008

できた。

WS000009

もう一個LiveJournalを追加してみる。

WS000011

LiveJournalでログインして許可する。

WS000013

登録できた。

 WS000014

LiveJournalのURLでもログインできます。

WS000015

 

hdknr.com

http://hdknr.com
No list items have been added yet.
Photo 1 of 56