OAuth 2.0 の仕組み
OAuth 2.0 は認可 (Authorization) の標準仕様として有志の手により策定されているオープンなプロトコルです。OAuth 2.0 を利用すると、ユーザはサードパーティ制アプリケーションにパスワードなど秘密情報を渡すことなく、限定されたアクセス権を与えることができます。
サードパーティ制アプリケーションで Google, Facebook, Twitter など(プロバイダと呼ばれます)を使ったログイン機能を提供するために使われることもありますが、OAuth 2.0 自体は利用者の本人確認を他のプロバイダに任せており、ユーザを認証済みと信頼してアクセス権を与える仕組みです。認証と認可には次のような違いがあります。
- 認証: 本人であることを証明し、検証者がそれを認める (e.g. OpenID, Email+パスワード)
- 認可: 認証済の利用者に対して限定されたアクセス権を与える (e.g. OAuth 2.0)
OAuth 2.0 は 2012 年 10 月に発行された RFC 6749 にて規定されています。
2009 年に生まれた OAuth 1.0 も、セキュリティ問題を修正されバージョン 1.0a として未だ現役で使われていますが、今回の記事では OAuth 2.0 のみを対象としています。
OAuth 2.0 とリソース
まず、役者は次の通りです。
- リソースオーナー (e.g. 山田太郎という個人)
- サービスプロバイダ (e.g. Google, Twitter)
- クライアント (サードパーティ制アプリケーション)
「リソースオーナー」という単語には馴染みの薄い人が多いと思います(私もそうです)が、「ユーザ」を「Google や Twitter といったサービスプロバイダに保存されているリソース(投稿した文章など)の所有者(owner)」として言及する際の呼び名と考えると、意味を捉えやすいかもしれません。
「OAuth 2.0 が認証ではない」ということはつまり、サービスプロバイダ側で認証済であれば、例えクライアントを操作する人間がリソースオーナーとは別人であっても OAuth 2.0 には「本人でないこと」を検知しアクセスを拒否する手段がない、ということです。
グラント種別
OAuth 2.0 を実現する場合、4 個のグラント種別(Grant Type)からひとつを選択します。
- Authorization Code (認可コード)
- Implicit Grant
- Password Credential Grant
- Client Credential Grant
今回は最もシンプルであり、IPA が「最も無難」であるとする (1) の "Authorization Code" を利用します。
結局のところ、Authorization Codeグラント種別を用いるのが最も無難である。
なお上の IPA セキュア・プログラミング講座では OAuth 2.0 に限らず Web アプリケーションを実装する上でのセキュリティがわかりやすく解説されており、一読するといろいろと得るものがあります。
OAuth 2.0 の流れ
OAuth 2.0 の全体の流れは次のように規定されています。
※ The OAuth 2.0 Authorization Framework より
Resource Owner と Client は先に出てきました。Authorization Server と Resource Server はひとまとまりで「サービスプロバイダ」と見たほうがわかりやすいかもしれません。OAuth 2.0 の仕様上、サービスの認可サーバとリソースを吐き出すサーバを分離することが可能であるためこのように書かれています。
上図はクライアントを中心として書かれていますが、これを左からリソースオーナー(ユーザ自身)、クライアント(ユーザの代わりにリクエストを行う代理人)、サービスプロバイダ(Authorization + Resource Server)の三者に並べ直してみると次のように描けます。
- クライアントはリソースへアクセスする認可を得たいので、リソースオーナーに「プロバイダから Authorization Code を入手してくれ」とお願いします。
- リソースオーナーはサービスプロバイダに本人であることを(パスワード等で)証明し、ログインを実行します
- 認証が成功します
- 続けてリソースオーナーはサービスプロバイダに対して「このリストにある情報をクライアントにアクセスする許可を与えたい」と意思表示します
- サービスプロバイダは許諾の意思表示を受け、Authorization Code をリソースオーナーに返します
- リソースオーナーは入手した Authorization Code をクライアントに渡します
- クライアントはリソースオーナーの許諾を受けた証拠である Authorization Code をサービスプロバイダに提示します
- クライアントはサービスプロバイダよりアクセストークンを受け取ります
- 以降、クライアントはアクセストークンを使うことでリソースオーナーに代わり限定されたサービスを利用することが出来ます。
それでは、実際にここまでの OAuth 2.0 認可フローを Ruby コードに落としこんで行こうと思いますが、まずリソースオーナーは人間(の操作するブラウザ)なので、AllAbout Ruby ガイドの記事として取り上げるべき箇所はさほどありません。
また、あなたがもし何らかの Web サービスを提供しておりユーザのリソースを預かっている場合は「クライアントに対して認可を与えるサービスプロバイダ部分」を実装することもあります。 しかしここを独自実装する必要がある人は少数派で、大抵の人が OAuth 2.0 に触れるときは既存のサービスプロバイダに対してクライアントを実装するケースだと思います。そこで、本記事の残りの部分では Ruby を使ってクライアント骨格部分の処理を書いてみます。
OAuth 2.0 プロトコルのクライアント処理を担う gem は既に作成されており、必要なパラメータを埋めるだけで比較的簡単にアクセストークンの取得まで辿り着くことができます。
次のページでは OAuth 2.0 の実例として、Ruby の oauth2 gem を使って Google APIs を利用してみます。