2007年11月23日

PylonsでOpenID

OpenID



OpenID は、複数のWebサービスに対して、URLで表される同一のユーザーIDを使う規格です。
まだ、対応しているサービスは少ないようですが、livedoorやはてなが、OpenIDの提供をはじめていますし、Microsoft, Mozilla も対応アプリケーションをリリースしていくということなので、今後のWebサービスを検討する上で、無視することはできないでしょう。



実際に、OpenID対応のWebアプリケーションを作る方法Pylons編です。



Authkit



AuthKitは、WSGI用の認証ミドルウェアです。
特に、PasteDeployの設定と相性が良く(そのように設計されているからですが)PasteベースのフレームワークであるPylonsでは、認証と承認を実装する際に良く使われています。



AuthKit以外にも、wsgiauthという認証ミドルウェアがあり、こちらもOpenIDをサポートしています。



PylonsでOpenID



基本的には、PylonsのWSGIアプリケーションにAuthKitのミドルウェアを被せるだけです。
Pylonsはmiddleware.pyでミドルウェアを設定できるようになっています。


from authkit.authenticate import middleware, sample_app
from beaker.middleware import SessionMiddleware

app = middleware(
app,
setup_method='openid, cookie',
openid_path_signedin='/mypage',
openid_store_type='file',
openid_store_config='',
openid_charset='UTF-8',
cookie_secret='secret encryption string',
cookie_signoutpath = '/signout',
)
app = SessionMiddleware(
app,
key='authkit.open_id',
secret='some secret',
)


PylonsAppが既に、Beakerセッションミドルウェアを含んでいますが、AuthKitをその外側に適用するため、さらにセッションミドルウェアを被せます。
設定は、直接キーワード引数で渡していますが、pastedeploy 経由で、設定可能です。
以下のように設定します。

[app:main]
...
authkit.setup.method=openid, cookie
authkit.openid.path.signedin=/mypage
authkit.openid.store.type=file
authkit.openid.store.config=
authkit.openid.charset=UTF-8
authkit.cookie.secret=secret encryption string
authkit.cookie.signoutpath = /signout

middleware.pyでは、キーワード引数のかわりに、app_configとglobal_configを渡します。

from authkit.authenticate import middleware, sample_app
from beaker.middleware import SessionMiddleware

app = middleware(
app,
app_conf=app_conf,
global_conf=global_conf,
)
app = SessionMiddleware(
app,
key='authkit.open_id',
secret='some secret',
)



保護したいメソッドを、デコレートします。
引数を受け取らないPylons特有のデコレーターが用意されているので、そちらを使用します。
※通常のWSGIアプリケーションインターフェイス(environとstart_responseを受け取る関数)の場合には、authkit.authorize.authorize を使います。

from authkit.pylons_adaptors import authorize
from authkit.permissions import RemoteUser
...
@authorize(RemoteUser())
def mypage(self):

return render('/mypage.mako')


ユーザー情報は、environ['REMOTE_USER']から取得できます。

<html xmlns="http://www.w3.org/1999/xhtml">
<head>
</head>
<body>
% if 'REMOTE_USER' in request.environ:
<span>${request.environ['REMOTE_USER']}</span>
% endif
</body>
</html>



参考