1

webpy の開発用 Web サーバーで python-openid を使用して OpenID 認証をテストしています。Yahoo! および myOpenID を使用すると、サーバーが check_authentication を拒否したというメッセージが表示された失敗応答が返されます。奇妙な部分は、私も正しいopenid.identity.

同じタイプの認証は、Google (@ https://www.google.com/accounts/o8/ud ...) でも問題なく機能します。一方で、それは私が何か正しいことをしているという自信を与えてくれますが、他方では、矛盾が私を混乱させます.

return_to&trust_rootは両方とも localhost:8080 であり、これに関係がある可能性があります。

ユーザーを Yahoo! に送信するために使用するコードは次のとおりです。認証する:

  def POST(self):
    post_data = web.input()
    if post_data.has_key('openid_identifier'):
      openid_identifier = post_data.get('openid_identifier')
      c = Consumer(session, openid.store.memstore.MemoryStore())
      auth = c.begin(openid_identifier)
      auth_url = auth.redirectURL('http://localhost:8080', return_to='http://localhost:8080/authenticate')
      raise web.seeother(auth_url)
    return post_data

auth_urlこの場合、次のように設定されています (読みやすいようにフォーマットされています):

https://open.login.yahooapis.com/openid/op/auth?
openid.assoc_handle=cYSO3wJSjQa3ewmRpaQz3YodzqjosP1ta.4TVzumqlLpAFM7oWci6K9bMKG4uuqZ.5m.fY7Wp8BWfQ1eR_soHWpJ6gCsKtxi_7Bqi22T5RUcMIuQBVjpGFSjc_kRY2k-&
openid.claimed_id=http%3A%2F%2Fspecs.openid.net%2Fauth%2F2.0%2Fidentifier_select&
openid.identity=http%3A%2F%2Fspecs.openid.net%2Fauth%2F2.0%2Fidentifier_select&
openid.mode=checkid_setup&
openid.ns=http%3A%2F%2Fspecs.openid.net%2Fauth%2F2.0&openid.realm=http%3A%2F%2Flocalhost%3A8080&
openid.return_to=http%3A%2F%2Flocalhost%3A8080%2Fauthenticate%3Fjanrain_nonce%3D2010-10-08T02%253A56%253A04ZrxAI

リターン URL でのハンドラーは次のようになります。

  def GET(self):
    data = web.input()
    c = Consumer(session, openid.store.memstore.MemoryStore())
    result = c.complete(dict(data), current_url='http://localhost:8080/authenticate')
    if result.status == SUCCESS:
      openid_identity = data.get('openid.identity')
      ...
    render = web.template.render('templates/', base='layout')
    return render.error(...)

resultgets に設定され<openid.consumer.consumer.FailureResponse id=None message='Server denied check_authentication'>data(戻り値のクエリ パラメータ) は次のように設定されます。

<Storage {'openid.op_endpoint': u'https://open.login.yahooapis.com/openid/op/auth', 
'openid.sig': u'yCHffpHs2Whtw9p1gPzC+ToQJ0k=', 
'openid.ns': u'http://specs.openid.net/auth/2.0', 
'janrain_nonce': u'2010-10-08T02:56:04ZrxAIWh', 
'openid.return_to': u'http://localhost:8080/authenticate?janrain_nonce=2010-10-08T02%3A56%3A04ZrxAIWh', 
'openid.pape.auth_level.nist': u'0', 
'openid.claimed_id': u'https://me.yahoo.com/a/d3eEQZAWydfmtDwaGB2vBEVU4vIMLsez#1ac56', 
'openid.mode': u'id_res', 
'openid.realm': u'http://localhost:8080', 
'openid.response_nonce': u'2010-10-08T02:55:52ZRLNmEd7aWiaGWjHfhqEQs2Fxj3.nXdwciA--', 
'openid.signed': u'assoc_handle,claimed_id,identity,mode,ns,op_endpoint,response_nonce,return_to,signed,pape.auth_level.nist', 
'openid.identity': u'https://me.yahoo.com/a/d3eEQZAWydfmtDwaGB2vBEVU4vIMLsez', 
'openid.assoc_handle': u'cYSO3wJSjQa3ewmRpaQz3YodzqjosP1ta.4TVzumqlLpAFM7oWci6K9bMKG4uuqZ.5m.fY7Wp8BWfQ1eR_soHWpJ6gCsKtxi_7Bqi22T5RUcMIuQBVjpGFSjc_kRY2k-'}>

それは確かに私には失敗の反応のようには見えません。設定されていることに注意してくださいopenid.identity。そうです、これが私の Yahoo! での OpenID ID です。

ここからこれをどこに持っていくべきかわかりません。何かアドバイスはありますか?

4

1 に答える 1

3

コンシューマには、検出と認証の間の状態を維持するためのデータ ストアが必要です。私が使用していたストアは、openid.store.memstore.MemoryStore()実際にはリクエスト間で状態を維持していませんでした。「メモリ」から期待されるように、プロセス内の状態のみを維持します(当然)。少し変更する必要があったのは、GET ハンドラーと POST ハンドラーの両方でのコンシューマーの作成です。

コンシューマーを作成する間違った方法は次のとおりです。

# BAD: MemoryStore() has a short memory -- within the process only
c = Consumer(session, openid.store.memstore.MemoryStore())

コンシューマを作成する正しい方法は次のとおりです。

# GOOD: MySQL has a long memory -- across processes
db = web.database(dbn='mysql', db='somedb', user='someuser', pw='')
conn = db._db_cursor().connection
cstore = sqlstore.MySQLStore(conn, 'openid_associations', 'openid_nonces')
c = Consumer(session, cstore)

関連ハンドルとノンスを覚えておくと役立つと思います。私はここで 10 時間立ち往生していたに違いないので、これが次の男 (またはギャル) が同じことを避けるのに役立つことを願っています.

これは私がこれまでに獲得した最初の懸賞金です。私自身のものです。ウット!

補足: これは、データベースに OpenID テーブルが設定されていることを前提としています。これは、MySQL では次のようになります。

create table openid_nonces (
  server_url blob not null,
  timestamp integer not null,
  salt char(40) not null,
  primary key (server_url(255), timestamp, salt)
) engine=InnoDB;

create table openid_associations (
  server_url blob not null,
  handle varchar(255) not null,
  secret blob not null,
  issued integer not null,
  lifetime integer not null,
  assoc_type varchar(64) not null,
  primary key (server_url(255), handle)
) engine=InnoDB;

特定のストアに関連する SQL ステートメントについては、ドキュメントの openid.store.sqlstore セクションを確認してください。

于 2010-10-10T06:07:26.143 に答える