OAuth 2.0のDraft 13出ました。
draft-ietf-oauth-v2-13 - The OAuth 2.0 Authorization Framework
Facebookやmixi Graph APIなどを使って開発されたことがある方は、OAuth 2.0 Draft 10の仕様はほぼ理解されていると思います。
Draft 10は単体である程度まとまった仕様として書かれていましたが、そのあとのDraft 11から構成の見直しなどが行われました。
もうそろそろ決まりそうだという噂があるので、今一度ざっくり最初からまとめ直していきます。
ただ、ClientやAuthorization Serverなど、基本的な説明は省略しています。
Draft 11以降に出てきた(と思われる)説明などを簡単にまとめたつもりです。
毎度のことながら、長いうえにこれは翻訳ではないので、厳密に調べたい方は原文を見てください。
あまりにも解釈間違っていそうな箇所があればご指摘をいただければと思います。
1. Introduction
既存のclient-server authenticationの問題と、OAuthだとどうなるかを説明しています。
詳細の説明は省略します。
1.1. Roles
登場人物と役割の説明です。
これもDraft 10までと変わりません。
- resource owner
- resource server
- client
- authorization server
詳細の説明は省略します。
1.2. Protocol Flow
Rolesとプロトコルフローですね。
ずっと前からありますけど、このAAみたいな説明って。。。
詳細の説明は省略します。
1.3. Access Token
Access Tokenの説明です。
前半は省略します。
大事なのは、後半の3,4行ぐらいですかね。
うまく一言で説明できませんが、一回Access Tokenに変換してResource Serverにアクセスすることで、Resouce Serverが色々な認証方法(例えば、basic認証と何と何と・・・)に対応しなくてもよくなり、Scopeなどの制限も可能になるということですね。
Access TokenはResource Serverのセキュリティ要件によって異なるフォーマット、構造、利用方法を持つことができるとあります。
7.1あたりで説明がありますが、この仕様ではAccess Tokenの詳細までは細かく定義されず、companion specificationsとして別で定義されていくことになります。
1.4. Authorization Grant
Authorization GrantはResource Owner/Server間の認可を抽象的に表す中間証明書的な一般用語です。(日本語おかしいな。。。)
Access Tokenを取得するために必要ですよと。ここでは、2種類のGrant Typeについての説明があります。
- Authorization Code
- implicit grant
Authorization Codeについて、ClientがResource OwnerのCredentialを扱うのではなく、Authorization Serverにユーザーを向けてそこで認証したあとにAuthorization Codeを受け取り、Access Tokenと交換します。
Authorization Codeを使うことにより、Clientが直接Resource OwnerのCredentialを扱うよりも安全ですね。
implicit grant ってのは、Authorization Codeを使わずに直接Access Tokenを返します。
少し前のDraftではUser-Agent Profileとか言われていたケースですね。呼び方が変わっています。
1.4.3. Resource Owner Password Credentials
Resource OwnerのIDやパスワードをauthorization grantとしてAccess Tokenを取得するために直接利用できます。
OAuth 1.0でいうxAuthの類です。basic認証と違うところは、最初にAccess Tokenに交換されるときだけ使いますよということですね。
1.4.4. Client Credentials
Resource Owner=clientの場合、Client Credentials(Client ID/Secret)をauthorization grantとして利用できます。
これは、2-legged OAuth とか言われていたフローに似ていますが、ここでも1回Access Tokenと交換したらOKだという点が違いますね。
1.4.5. Extensions
上記のgrant typesに加えて、OAuthと他のtrust frameworksをつなぐgrant typesを定義しても良いとあります。
MLなどで検討されている代表的なものは、SAMLとのつなぎですね。
下記の仕様では、SAML 2.0 bearer assertion grant typeが定義されていて、SAMLを使うシステムとOAuthを使うシステムを連携させることができます。
1.5. Refresh Token
Refresh Tokenの説明です。
詳細の説明は省略します。
2. Protocol Endpoints
このプロトコルで利用するエンドポイントは2つです。
- Authorization endpoint
- Token endpoint
とはいえ、上で説明したgrant typeの中にはこの2つのうち1つしか使わないものもあります。
Extension grant typeで他のframeworkとつなぐ場合などは他にエンドポイントが必要になるかもしれません。そういうのは別で定義されることになりますね。
2.1. Authorization Endpoint
Authorization Endpointの説明です。
3. Client Authentication
Crient CredentialはClientの特定/認証に用いられます。
Client Password Authenticationは共有秘密鍵を用いたClient認証です。
- client_id : clientの識別子
- client_secret : clientのパスワード
それ以外のClient Authenticationについても利用できるとありますが、細かく書かれていません。
4. Obtaining Authorization
やっとここまできた。。。ここに実際のリクエスト/レスポンスが書いてあります。
各grant type毎のAuthorization取得のフローの説明が書いてあります。
4.1. Authorization Code
Draft 10では"web server profile"として定義されていたフローです。
grant type : "Authorization Code" の対象であるClient
- client credentialを安全に保存できる
- ブラウザを用いたリダイレクトができる
- Authorization Serverと直接通信が可能
フローは以下の通りです。
+----------+ | resource | | owner | | | +----------+ ^ | (B) +----|-----+ Client Identifier +---------------+ | -+----(A)--- & Redirect URI ------>| | | User- | | Authorization | | Agent -+----(B)-- User authenticates --->| Server | | | | | | -+----(C)-- Authorization Code ---<| | +-|----|---+ +---------------+ | | ^ v (A) (C) | | | | | | ^ v | | +---------+ | | | |>---(D)-- Client Credentials, --------' | | | Authorization Code, | | Client | & Redirect URI | | | | | |<---(E)----- Access Token -------------------' +---------+ (w/ Optional Refresh Token) Figure 3: Authorization Code Flow
Authorization Requestは以下のパラメータを含む"application/x-www-form-urlencoded"形式のリクエストをauthorization endpoint URIに送信します。
- response_type : "code"
- client_id
- redirect_uri
- scope
- state
サンプルリクエストはこちらです。
GET /authorize?response_type=code&client_id=s6BhdRkqt3& redirect_uri=https%3A%2F%2Fclient%2Eexample%2Ecom%2Fcb HTTP/1.1 Host: server.example.com
Authorization Responseは以下のパラメータを含みます。
- code
- state
こちらも"application/x-www-form-urlencoded"形式です。
サンプルレスポンスはこちらです。
HTTP/1.1 302 Found Location: https://client.example.com/cb?code=i1WsRn1uB1
エラーレスポンスは省略します。
Access Token Requestは以下のパラメータとClient Credentialを含む"application/x-www-form-urlencoded"形式のリクエストをtoken endpoint URIに送信します。
- grant_type : "authorization_code"
- code
- redirect_uri
POST /token HTTP/1.1 Host: server.example.com Content-Type: application/x-www-form-urlencoded grant_type=authorization_code&client_id=s6BhdRkqt3& client_secret=gX1fBat3bV&code=i1WsRn1uB1& redirect_uri=https%3A%2F%2Fclient%2Eexample%2Ecom%2Fcb
このレスポンスは 5.1, 5.2あたりで説明されています。
成功するとAccess Token, Refresh Tokenなどが返されます。
HTTP/1.1 200 OK Content-Type: application/json Cache-Control: no-store { "access_token":"SlAV32hkKG", "token_type":"example", "expires_in":3600, "refresh_token":"8xLOxBtZp8", "example_parameter":"example-value" }
Draft 10の仕様と比べて、token_typeというパラメータが追加されています。
これがAccess Token Typesってもので、後で説明があります。
これはもっとも標準的なフローなので問題ないですね。
4.2. Implicit Grant
Draft 10では"user-agent profile"として定義されていたフローです。
grant type : "Implicit Grant" の対象であるClient
- client secretを安全に保存できないJavaScriptやNativeのアプリケーション
- ブラウザを用いたリダイレクトができる
- フラグメント要素の値を扱える
フローは以下の通り。
+----------+ | Resource | | Owner | | | +----------+ ^ | (B) +----|-----+ Client Identifier +---------------+ | -+----(A)--- & Redirect URI ----->| | | User- | | Authorization | | Agent -|----(B)-- User authenticates -->| Server | | | | | | |<---(C)---- Redirect URI ------<| | | | with Access Token +---------------+ | | in Fragment | | +---------------+ | |----(D)---- Redirect URI ------>| Web Server | | | without Fragment | with Client | | | | Resource | | (F) |<---(E)------- Script ---------<| | | | +---------------+ +-|--------+ | | (A) (G) Access Token | | ^ v +---------+ | | | Client | | | +---------+ Figure 4: Implicit Grant Flow
Authorization Requestは以下のパラメータを含む"application/x-www-form-urlencoded"形式のリクエストをauthorization endpoint URIに送信します。
- response_type : "token"
- client_id
- redirect_uri
- scope
- state
サンプルリクエストはこちらです
GET /authorize?response_type=token&client_id=s6BhdRkqt3& redirect_uri=https%3A%2F%2Fclient%2Eexample%2Ecom%2Fcb HTTP/1.1 Host: server.example.com
この後、ユーザー認証/認可の取得を行い、リダイレクトのレスポンスにAccess Tokenを含みます。
Access Token Responseは以下のパラメータをフラグメントとして付加した"application/x-www-form-urlencoded"形式となります。
- access_token
- token_type
- expires_in
- scope
- state
HTTP/1.1 302 Found Location: http://example.com/rd#access_token=FJQbwq9& token_type=example&expires_in=3600
エラーレスポンスは省略します。
4.3. Resource Owner Password Credentials
ユーザーのID/PWを利用してAccess Tokenを取得するフローの説明です。
grant type : "Resource Owner Password Credentials" の対象であるClient
- ユーザーのcredentialを取得できる
- Authorization Serverと直接通信が可能
フローは以下の通りです。
+----------+ | Resource | | Owner | | | +----------+ v | (A) Password Credentials | v +---------+ +---------------+ | | Client Credentials | | | |>--(B)---- & Resource Owner ----->| | | Client | Password Credentials | Authorization | | | | Server | | |<--(C)---- Access Token ---------<| | | | (w/ Optional Refresh Token) | | +---------+ +---------------+ Figure 5: Resource Owner Password Credentials Flow
Authorization endpointを利用せずに、直接Token EndpointにAccess Tokenを要求します。
Access Token Requestは以下のパラメータとClient Credentialを含む"application/x-www-form-urlencoded"形式のリクエストをtoken endpoint URIに送信します。
- grant_type : "password"
- username
- password
- scope
サンプルリクエストはこちらです。
POST /token HTTP/1.1 Host: server.example.com Content-Type: application/x-www-form-urlencoded grant_type=password&client_id=s6BhdRkqt3& client_secret=47HDu8s&username=johndoe&password=A3ddj3w
Access Token ResponseはAuthorization Codeの場合と同様です。
HTTP/1.1 200 OK Content-Type: application/json Cache-Control: no-store { "access_token":"SlAV32hkKG", "token_type":"example", "expires_in":3600, "refresh_token":"8xLOxBtZp8", "example_parameter":"example-value" }
4.4. Client Credentials
Client CredentialのみでAccess Tokenを取得するフローの説明です。
Draft 10では"Autonomous clients "として説明されていたフローの一つです。
フローは以下の通りです。
+---------+ +---------------+ | | | | | |>--(A)--- Client Credentials ---->| Authorization | | Client | | Server | | |<--(B)---- Access Token ---------<| | | | (w/ Optional Refresh Token) | | +---------+ +---------------+ Figure 6: Client Credentials Flow
Authorization endpointを利用せずに、直接Token EndpointにAccess Tokenを要求する。
Access Token Requestは以下のパラメータとClient Credentialを含む"application/x-www-form-urlencoded"形式のリクエストをtoken endpoint URIに送信します。
- grant_type : "client_credentials"
- scope
POST /token HTTP/1.1 Host: server.example.com Content-Type: application/x-www-form-urlencoded grant_type=client_credentials&client_id=s6BhdRkqt3& client_secret=47HDu8s
Access Token ResponseはAuthorization Code, Resource Owner Password Credentialsの場合と同様です。
4.5. Extensions
上記に含まれないフローをExtentionsとして利用可能です。
extension grant typeのときは、grant_typeパラメータに絶対URIを指定します。
必要に応じてパラメータを追加します。
サンプルはこちらです。
POST /token HTTP/1.1 Host: server.example.com Content-Type: application/x-www-form-urlencoded grant_type=http%3A%2F%2Foauth.net%2Fgrant_type%2Fassertion%2F saml%2F2.0%2Fbearer&assertion=PEFzc2VydGlvbiBJc3N1ZUluc3RhbnQ [...omitted for brevity...]V0aG5TdGF0ZW1lbnQ-PC9Bc3NlcnRpb24-
こうやってExtensionとして新しいGrant Typeを受け入れられるようになっていれば、あとからユースケースと実装方法が出てきたときに「OAuth 2.0って○○のときつかえねーじゃん」って言われなくなりますね。
5. Issuing an Access Token
Token Endpointが返すAccess Token発行レスポンスの説明です。
5.1. Successful Response
成功レスポンスの説明です。
200 (OK) + JSONを返します。
詳細の説明は省略します。
5.2. Error Response
エラーレスポンスの説明です。
HTTP 400 (Bad Request)+JSONを返します。
詳細の説明は省略します。
6. Refreshing an Access Token
Access Tokenの更新方法の説明です。
リクエストパラメータは以下の3つとclient credentialです。
- grant_type : "refresh_token"
- refresh_token :
- scope : 更新後のAccess Tokenに求めるScope
client credentialにclient_id/client_secretを用いた場合のサンプルです。
POST /token HTTP/1.1 Host: server.example.com Content-Type: application/x-www-form-urlencoded grant_type=refresh_token&client_id=s6BhdRkqt3& client_secret=8eSEIpnqmM&refresh_token=n4E9O119d
レスポンスは5.1/5.2と同じです。
Authorization ServerはRefresh Tokenを更新しても良いし、そのままでも問題ありません。
7. Accessing Protected Resources
clientはresource serverにAccess Tokenを提出することで保護されたリソースにアクセスします。
resource serverはAccess TokenがExpireとScooeの有効性を必ず確認します。
Access Tokenの使い方はTypeに依存します。
一般的には、Access Token Typesの仕様のAuthentication Scemeに従ったHTTP "Authorization" Request Headerを使う必要があります。
あえて、Access Tokenの詳細まではこの仕様では定義しません。
7.1. Access Token Types
Access Token Typeは、clientが保護リソースにうまくアクセスするためのAccess Tokenの使い方をそのType特有の属性とともに提供します。
ここでは2つの例が示されています。
1つ目はtoken type : "bearer"です。
これが、最初から提案されていた"Token SecretなしのAccess Tokenのみのリクエスト"を送る際の「Access Tokenの使い方」ということになります。
GET /resource/1 HTTP/1.1 Host: example.com Authorization: BEARER h480djs93hd8
詳細はこちらの仕様で定義されています。 draft-ietf-oauth-v2-bearer-02 - The OAuth 2.0 Authorization Framework: Bearer Token Usage
これもあとで読みましょう。
もう1つが、token type : "mac" です。
これは以前読んで紹介した内容です。
OAuth 2.0 draft 12で出てきたMAC Tokenとは - r-weblife
GET /resource/1 HTTP/1.1 Host: example.com Authorization: MAC token="h480djs93hd8", timestamp="137131200", nonce="dj83hs9s", signature="kDZvddkndxvhGRXZhvuDjEWhGeE="
Access Token, Access Token SecretからSignatureを作成してリクエストを作成する方法が定義されています。
http://tools.ietf.org/html/draft-hammer-oauth-v2-mac-token-02
"mac" tokenで署名作成に利用されるToken SecretはAccess TokenとともにClientに渡されるわけなので、リソースアクセス以外の部分も各Typesの仕様に含まれるということになります。
8. Extensibility
訳すと"拡張性"となりますが、このOAuth 2.0の仕様に書かれているリクエスト、レスポンスが全てのユースケースに対応しているというわけではありません。
基本的な流れや制約はこの仕様で定義されていますが、下記の項目については、拡張性を持たせることで、様々なユースケースに対応できるようにしていると思われます。
- Access Token Types
- New Endpoint Parameters
- New Authorization Grant Types
といっても、自由すぎてはOAuth 1.0のときのようになってしまうため、説明があります。
8.1. Defining Access Token Types
Access Token Typesは2種類の定義方法があります。
(2)については、一般的な使われ方ではない"vendor-specific implementations"に限られるべきとあります。
一般的な使い方ならレジストリに登録して偉い人のお墨付きをもらってみんなで使いましょうよと。
(1)については、10.1で説明がありますが、ちゃんとレジストリに登録しなければならなく、type-nameは以下のABNFに従います。
type-name = 1*name-char name-char = "-" / "." / "_" / DIGIT / ALPHA
Typeの定義が新しいHTTP authentication schemeを含むときは、それを特定できる名前にすべきですよと。
少し前に紹介したHTTP Authentication: MAC Authenticationはこれにあたりますね。
8.2. Defining New Endpoint Parameters
リクエスト/レスポンスパラメータも、2種類の定義方法があります。
Access Token Typesと同じ感じですね。
この仕様に書いてあるリクエスト/レスポンスパラメータについては、10.2で説明されていますが、全部レジストリに登録してあ(ることにな)ります。
以下のABNFに従い、"x_"のプレフィックスは使ってはいけませんよということです。
type-name = 1*name-char name-char = "-" / "." / "_" / DIGIT / ALPHA
そして、Vendor-specific parameterとして、"x_"つきのパラメータも定義可能です。
OAuth 1.0時代のxAuthのような独自パラメータも定義可能なわけですが、よっぽど特別な使い方するとき以外は、IANA登録してみんなのヒーローになる方がいいですね!
10. IANA Registration
10.1. The OAuth Access Token Type Registry
OAuth 2.0では、Access Token Typesのレジストリが用意されます。
IANAとIESGあたりのしくみはこちら。
[http://tools.ietf.org/html/rfc5226
新たなAccess Token Typesの登録リクエストは、まだTBDだけど(なんとか@ietf.org)というMLにリクエストを投げます。
14日以内にDesignated Expert達が合否を決めて、IANAに連絡。
21日過ぎても未決定のリクエストは、MLを使ってIESGの偉い人にアピールすることができます。
登録のときのテンプレートはこんな感じ。
- Type name
- Additional Token Endpoint Response Parameters
- HTTP Authentication Scheme(s)
- Change controller
- Specification document(s)
10.2. The OAuth Parameters Registry
OAuth 2.0のパラメータレジストリも用意されます。
テンプレはこのような感じです。
- Parameter name
- Parameter usage location
- Change controller
- Specification document(s)
今まで説明してきたパラメータは初期登録されていますよと。
まとめ
むりやり3行でまとめると
- 認可のパターンとして、4パターン+αが定義されている (Authorization Code,Implicit Grant,Resource Owner Password Credentials,Client Credentials,Extensions)
- Access Token Typesはこの仕様では定義せずに、拡張性を持たせている。
- パラメータ、Access Token Types、Grant Typesは基本的にIANAへの登録が必要
ってとこでしょうか。
なぜ95%と言ってるのか?
このMLのpptxファイルに書いてありました。
OAuth 2 - 95%
次回のIIWまでにはもう変更なしの状態まで持っていく感じでしょうかねぇ。
おわり
いやー、長かったですね。。。これでもだいぶ端折るように頑張ったつもりですが。
まぁ、翻訳するとしたら、Draft 10翻訳時のノウハウがある程度利用できそうです。
日本の企業から、新しいAccess Token TypesやGrant Typeが提案されたりすると面白いと思います。
ではまた!