OpenID を使用して、Tornado を使用して構築された OpenID 認証サービスで認証する Tornado フレームワークを使用して Web サイトを構築しようとしています。
tornado.auth.OpenIdMixin に基づいて子クラスを作成し、Tornado アプリで認証ハンドラーとして使用しています。
class MyMixin(tornado.auth.OpenIdMixin):
_OPENID_ENDPOINT = "http://myserver.com/openidserver"
def authorize_redirect(self, oauth_scope, callback_uri=None, ax_attrs=["name", "email", "language", "username"]):
callback_uri = callback_uri or self.request.uri
args = self._openid_args(callback_uri, ax_attrs=ax_attrs)
self.redirect(self._OPENID_ENDPOINT + "?" + urllib_parse.urlencode(args))
def get_authenticated_user(self, callback):
tornado.auth.OpenIdMixin.get_authenticated_user(self, callback)
アプリケーションのハンドラ クラスは次のとおりです。
class AuthHandler(BaseHandler, MyMixin):
@tornado.web.asynchronous
def get(self):
if self.get_argument("openid.mode", None):
self.get_authenticated_user(self.async_callback(self._on_auth))
return
self.authenticate_redirect()
def _on_auth(self, user):
if not user:
self.send_error(500)
self.set_secure_cookie("user", tornado.escape.json_encode(user), expires_days=0.01)
self.redirect("/")
このコードは、GoogleMixin クラスが行っていることと、http: //technobeans.wordpress.com/2012/09/04/tornado-third-party-authentication/ でオンラインで見つけた例に基づいています。
OpenID サーバーについては、 https ://github.com/openid/python-openidの server.py から始めましたが、いくつかの問題が発生した後、 https://github.com/mrjj/citoも試しました。どちらのサーバーにもログインできるアカウントがありますが、どちらの場合もクライアント側で同じ問題が発生しています。
私の目標は、私がログインしていないことをクライアントに認識させ、OpenID サーバーにリダイレクトし、そこで認証し、ID を使用して認証する許可をクライアントに与え、そこから先に進むためにクライアントにリダイレクトされるようにすることです。
しかし、両方のサーバーで、ユーザーパラメーターが None であるため、クライアントは常に AuthHandler._on_auth() で失敗します。
これは、クライアントを実行している Tornado の出力です。
ERROR:root:Exception after headers written
Traceback (most recent call last):
File "/usr/lib/python2.7/dist-packages/tornado/web.py", line 897, in wrapper
return callback(*args, **kwargs)
File "website.py", line 67, in _on_auth
self.redirect("/")
File "/usr/lib/python2.7/dist-packages/tornado/web.py", line 412, in redirect
raise Exception("Cannot redirect after headers have been written")
Exception: Cannot redirect after headers have been written
いくつかのデバッグprint
ステートメントを追加した後、user
変数が空であるため、HTTP/500 エラーが発生していることがわかります。
OpenID がどのように機能するかはよくわかりませんが、OpenID がどのように機能するかを示す実用的な例が見つかりません。前後にたくさんの矢印が付いた図がいくつかありますが、もう少し技術的な詳細が記載されているものはありません。
私が調べた無料のサーバーはすべて、同じ基本機能セットを提供しているようです。
- 認証プロセスを開始するための正しい URL を指していますか?
- クライアントの OpenID 処理でいくつかのステップが抜けていて、Google が OpenID+OAuth プロトコルで行っていることとあまりにも似ているのでしょうか?