AOLのOpenAuthがチャレンジング過ぎて
AOLのOpenAuthという認証APIがあります。YahooのBBAuthだったり、Google Account Authentication、日本で言うならはてな認証、livedoor Authなどに代表される、最近流行のサービスプロバイダによる認証APIの一種なんだと思います。ただ、少なくともAOL IDを使うことはほぼないから、アナウンスは聞いてもとりあえずスルーしてたのだけど、たまたま仕様を読んでいたらかなりびっくりした。なんと通信経路にJSONPを使って認証トークンをやり取りできてしまう。JSONPはパブリック情報の配信以外に使うな、ってのが常識になりつつあった人たちから見たら、これはたぶん衝撃。
でも、これがセキュリティ的にヤバいかっていうと、決してそうではなくって、OpenAuthではいわゆる「リファラによるサイト制限」を実装しているところがポイント。つまり、JSONPリクエストしてくるWebサイトをブラウザが送ってくるリファラヘッダで認識して、それが「あらかじめ登録されたサイト」でありかつ「ユーザが同意したサイト」である場合のみ通信ができるようにサーバ側でアクセスコントロールをしているのだ。
JSONPを使うため、認証*1するために特にサーバサイドプログラムは要りません。全部HTML+JavaScriptでできます。
JSONPを使う場合のユーザ名取得方法
まず、ユーザ名を取得するWebページでは、IFRAMEで以下のページを表示しておく
https://api.screenname.aol.com/auth/login?devId=sh1Zdpo7rRtRzZ1b
ここでdevIdはAOLでDeveloper登録したときにもらえるキー。
http://dev.aol.com/keys
AOLにログインしていない状態ではログインボックスが、既にログイン済みの場合は、「このWebサイトにユーザ情報を教えていいですか」という旨の確認の画面が表示される。ここでユーザが同意して「Continue」ボタンを押すと、IFRAMEの親ページにFragment identifierとしてAUTHDONEという文字列が渡ってくる。
Webページはこのイベントを検知したら、以下のJSONPリクエストを送信する。
https://api.screenname.aol.com/auth/getToken?devId=sh1Zdpo7rRtRzZ1b&f=json&c=handleToken
パラメータ c でjsonpのコールバック関数名を指定している。以下のJSONPレスポンスが返ってくる。
handleToken({"response":{"statusText":"OK","data":{"token":{"expiresIn":"86400","a":"%2FwEAAAAAJ.....cfXlhIQ%3D"}},"statusCode":"200"}})
これによって認証トークン(response.data.token.aの値)が得られるので、あとはこの値をパラメータに使って再びJSONPコールをすることでユーザ情報を取得できる。
https://api.screenname.aol.com/auth/getInfo?devId=sh1Zdpo7rRtRzZ1b&f=json&a=%2FwEAAAAAJ.....cfXlhIQ%3D&c=handleInfo
帰ってくる情報はたとえば以下のような感じ。AOLのユーザログインIDがとれているのがわかる。
{"response":{"statusText":"OK","data":{"userData":{"attributes":{},"md5Verified":"false","loginId":"shinichitomita","lastAuth":"1182096932000"}},"statusCode":"200"}}
考察
以上の手続きだけではあくまでIDを自動的にクレーム(主張)してもらっているだけなので、認証とは厳密には言えない。ユーザは他の人のIDを適当に主張することも出来る。認証する場合はちゃんとサーバ側でVerifyをする必要があるだろう。あと、IFRAMEにログインボックスを入れるというのは、フィッシングのことを考えるとあまり好ましくない実装に思える。その場合はリダイレクトのインターフェースも提供されているから、まあそっちを使えばいいのだけど。
しかしチャレンジング過ぎる。リファラでJSONPのアクセス制限セキュリティってのは、自分も昔考えていたけれども、厳密にそれで脆弱性がないのかどうかの確証がなく(そういう用法に対してネガティブなコメントをもらったこともあり)、もう無理なのかなー、とか考えていた。
でもAOLはやっちゃったね。もはや老いた(?)とはいえ結構インパクトを持てる企業ではあるわけで。これは一体今後どうなるんだろう。注目したい。
*1:正確にはユーザの「クレーム(主張)」ではあるけど