OpenIDファウンデーション・ジャパン

テキスト

OpenID Connect, ふたつのトークンの物語

「なぜ OpenID Connect にはトークンが二種類あるの?」という質問を、たびたびもらいます。そこにはいくつかの設計上の要件があり、わたしたちは仕様策定のなかで議論してきました。

1 - RP (リライング・パーティ) からの要件は、ログイン後のユーザー・インタフェースの簡便なカスタマイゼーションです。

  • そこでは、ユーザーへのレスポンスを一秒以下で行うことが求められました。つまり、ユーザー ID を取得するための、IdP へのさらなるラウンドトリップ (問い合わせ) は許されなかったのです。パスワードによる認証に加えて数秒の遅延が発生するようでは、実際に使うことはできないと、多くの RP が考えています。
  • Facebook は署名つきリクエスト (signed request) を用いて、ユーザー ID をレスポンスに格納して返却しています。クライアント (RP) は署名を検証し、ユーザー・インタフェースを即座に表示することが可能です。

2 - Salesforce や他の IdP には、既にユーザー情報 (user-info) エンドポイントとその他保護リソースが存在しており、これらに対するアクセスをスコープとしてアクセス・トークンに追加したいと考えています。

  • ここでの要件は、異なるアクセス・トークンの形式が強制されることで、既存の実装を変更しなくてはならなくなるようなことは避けたい、ということでした。

3 - T-Mobile 他では、署名つきトークン (signed token) にスコープを含め、エンドポイントに渡しています。

  • 彼らの要件は、トークンに必要な情報だけを格納し、保護リソースに渡す、ということです。リソースは第三者に管理されていることもありうるため、ユーザー ID を送信することは、プライバシー情報の漏洩につながりかねません。


4 - Google 他の要件は、Connect が複数種類のクライアント、とくにブラウザ内の Ajax をサポートすることでした。

5 - リソースごとに毎回ユーザーに認可を求めることはできない、ということには、全員が同意しました。

まず、要件 1 を満たすには、RP に対して user_id の入った署名つきトークンを送る必要があり、そして、そのトークンは認可サーバー (Authorization Server) からのレスポンスに含まれていなくてはないことがわかります。
よって、id_token が必要なのです。Facebook には、署名つきリクエスト (signed request) という独自形式のしくみがあります。わたしたちコミュニティは、JWT という、より汎用的でオープンな標準を考案しました。これは署名つきリクエストと似ており、加えて暗号化もサポートします。

OAuth 2.0 の手法のひとつとして、異なる保護リソースに対して複数のトークンを生成することを、ダウンスコーピング (down-scoping) といいます。各リソースごとに、認可リクエストにおいて、複数のスコープを要求するのです。
認可サーバーは、すべてのスコープに対して有効なリフレッシュ・トークン (Refresh Token) を提供します。そしてこのトークンをトークン・エンドポイントに提示し、全てではなく一部のスコープに対する新しいトークンを要求することになります。

ダウンスコーピングにはいくつか問題がありますが、最も大きなものは、これが code フローでしか使えないため、要件 1 と 4 を満たせないということです。

これに対し、いくつかの選択肢があります:

  1. id_token をアクセス・トークンとして用いる
  2. アクセス・トークンを id_token に含める
  3. ふたつのトークンを返却する

id_token をアクセス・トークンとして用いる方法では、要件 2 を満たせませんし、長い期間有効となるアクセス・トークンがセッション・クッキーとなってブラウザーに保管されるかもしれないという、新たなセキュリティ上の懸念が生じます。

アクセス・トークンを id_token に含めるやりかたは、Facebook Connect が選択した方法と同じです。要件 1 と 2 に対してはうまくいきますが、やはりいくつか問題があります。それは、id_token をセッション管理に用いたいと RP が考えた場合です。そのためにはセッション・クッキーに長期間有効なアクセス・トークンを埋め込むことになりますが、id_token のサイズがかなり大きくなってしまいます。要件 3 は満たせたとしても、アクセス・トークンにはその他のユーザー情報を載せることができません。

認可サーバーからのレスポンスとしてふたつのトークンを返却することで、すべての要件を満たすことができます。

  •  認証されたユーザーの情報が、アクセス・トークンから切り離される
  •  id_token のサイズをかなり小さくすることができる
  •  id-token をセッション・クッキーとして用いる場合にも、アクセス・トークンは漏洩しない
  •  アクセス・トークンを署名つきトークンにすることができ、さらに必要な情報だけを含めることができる
  •  code フローを用いる場合に、引き続きダウンスコーピングを行うことができる
  •  id_token をユーザー・セッションの生存期間と結びつけることが可能であり、一方、アクセス・トークンの生存期間とは切り離すことができる
  •  ふたつのトークンの受け手 (audience) を分けることができるため、それぞれの受け手に合わせた暗号化を行うことが容易となる

一般的に、 OAuth 2.0 の implicitフローを用いる RP では、あらかじめ登録されたリダイレクト・エンドポイントに認可サーバーから返却されたレスポンスの中から、id_token を取り出します。次に署名を検証し、そこに含まれる user_id を用いて Web ページをカスタマイズする一方、もし必要であればさらに、OAuth 2.0 によって認証されたリクエストを user_info エンドポイントに対して行います。これにより、再度アクセスしてきたユーザーのログイン処理を、RP が許容することのできる時間内に行うことができるようになります。新規ユーザーの場合であっても、比較して少し時間はかかりますが、プロファイル情報を取得することが可能です。

OpenID Connect に関連して、新規の OAuth 2.0 response_type が複数登録されています。これによって、クライアントからの様々な要求を満たすためのトークンの返却方法に、いくつかの選択肢が生まれることになります。

id_token を活用した、セッション管理およびシングル・ログアウト拡張についても、現在検討中です。

トークンを分離することについては、現在 OASIS の SAML WG がセッション・トークン・プロファイルの公開レビューを行っており、おそらくそこで部分的にですが検証が行われることになるでしょう。

トークンをひとつにすることは一見魅力的ですが、たくさんの理由から、わたしたちのユースケースの多くに対してはうまくいきません。わたしも単一の JWT トークンを主張していた一人ですが、結局負けました。

近いうちに、OpenID Connect  の response_typeについて投稿したいと思います。

John B.

(出典: thread-safe.com)

コメントを見る
水曜日, 11月 16 2011に公開. タグ:: openid
16
リアクション
  1. oauth-jpがoidfjからリブログしました
  2. kyomichiがoidfjからリブログして、コメントを追加しました:
    “id-token をセッション・クッキーとして用いる場合にも、アクセス・トークンは漏洩しない”
  3. takumakeiがoidfjからリブログしました
  4. yoshaがこの投稿を「スキ!」と言っています
  5. ishibashiがoidfjからリブログしました
  6. sakimuraがoidfjからリブログしました
  7. oidfjの投稿です

OpenIDファウンデーション・ジャパン OIDF-Jの公式ブログです。Open Identity に関する様々な情報をお届けします!WebサイトとFacebookページはこちら。
http://www.openid.or.jp/
http://www.facebook.com/openid.jp
前へ