4

我正在尝试使用 Tornado 框架构建一个网站,该框架使用 OpenID 对 OpenID 身份验证服务进行身份验证,该服务也是使用 Tornado 构建的。

我创建了一个基于 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 对我进行身份验证的权限,然后被重定向到客户端以从那里继续前进。

但是对于两台服务器,我的客户端总是在 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 应该如何工作的实际示例。有一些图表带有很多来回箭头,但没有更多的技术细节。

我看过的所有免费可用的服务器似乎都提供了相同的基本功能集。

  • 我是否指向正确的 URL 以启动身份验证过程?
  • 我是否在客户的 OpenID 处理过程中遗漏了一些步骤,并且它看起来太像 Google 使用他们的 OpenID+OAuth 协议所做的事情了?
4

0 回答 0