我正在尝试使用Tornado框架构建一个网站,该框架使用OpenID通过OpenID身份验证服务进行身份验证,该服务也是使用Tornado构建的。
我已经创建了一个基于tornado.auth.OpenIdMixin的子类,并使用它作为我的Tornado应用程序中的authenticaton处理程序:
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/
在线找到的示例对于我从https://github.com/openid/python-openid开始使用server.py的OpenID服务器,但在遇到一些问题之后我也尝试了https://github.com/mrjj/cito。在这两个服务器中,我都有一个可供我登录的帐户,但两次我在客户端遇到同样的问题。
我的目标是让我的客户端看到我没有登录,将我重定向到OpenID服务器,我在那里进行身份验证,授予客户端使用ID对我进行身份验证的权限,并被重定向到客户端以继续那里。
但是对于两台服务器,我的客户端始终在AuthHandler._on_auth()中失败,因为用户参数为None。
这是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
语句后,我知道我得到的HTTP / 500错误是因为user
变量为空。
我知道我不太明白OpenID应该如何工作,但我找不到OpenID应该如何工作的实际例子。有一些图表有很多箭头来回,但没有更多的技术细节。
我看过的所有免费服务器似乎都提供相同的基本功能集。