OAuth 2.0になると2-legged OAuthはどうなってしまうのか

こんばんは、ritouです。
今回は、OpenSocial等で利用されている2-legged OAuthがOAuth 2.0時代になるとどうなってしまうのかをちょっと考えました。

けっこう使われている2-legged OAuth

説明は省略します。
2-legged OAuthによるAPIアクセス << mixi Developer Center (ミクシィ デベロッパーセンター)

下記のような特徴があります。

  • Consumer Key をリクエストに含み、Signatureによりそのリクエストを検証可能
  • Timestamp,nonceもついてる

で、これがOAuth 2.0時代になるとどうなるかを考えます。

OAuth 2.0だとどうなるのか

OAuth 2.0の仕様とは、簡単に言うと"なんとかしてAccess Tokenを取得"して、あとはそれを使って"なんとかしてリソースアクセスする"ってことが書いてあるだけです。

2-legged OAuthのようなClient自体のリソースを扱うパターンもある程度想定されており、こんな感じになります。

  • Client CredentialからAccess Tokenに変換
  • Access Tokenを用いてリソースアクセス

仕様で言うと、この辺りです。
4.4. Client Credentials

     +---------+                                  +---------------+
     |         |                                  |               |
     |         |>--(A)--- Client Credentials ---->| Authorization |
     | Client  |                                  |     Server    |
     |         |<--(B)---- Access Token ---------<|               |
     |         |    (w/ Optional Refresh Token)   |               |
     +---------+                                  +---------------+


                     Figure 6: Client Credentials Flow

(A)のAccess Tokenを要求するRequestはこんな感じです。

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
(値は適当です)

(B)のレスポンスについては、Access Tokenのタイプにより異なります。
今回はAccess Token Typeとして拡張定義されているBearer/Mac Tokenの場合にどのようなフローになるのかを見てみましょう。

Client CredentialからBearer Tokenに変換

Access Tokenが返されるとこからです。

HTTP/1.1 200 OK
Content-Type: application/json
Cache-Control: no-store

{
  "access_token":"SlAV32hkKG",
  "token_type":"bearer",
  "expires_in":3600,
  "refresh_token":"8xLOxBtZp8",
  "example_parameter":"example-value"
}
(値は適当です)

リソースアクセスはこの通りです。
そのまま使うだけですね。

GET /resource/1 HTTP/1.1
Host: example.com
Authorization: BEARER SlAV32hkKG
(値は適当です)

HTTPS(っていうかTLS 1.2)が必須になるとはいえ、署名がないので今までの2-legged OAuthを使っていた人は物足りないですよね。
では、次にMAC Tokenの方を見てみます。

Client CredentialからMac Tokenに変換

Access Tokenが返されるとこからです。

HTTP/1.1 200 OK
Content-Type: application/json
Cache-Control: no-store

{
  "access_token":"SlAV32hkKG",
  "token_type":"mac",
  "secret":"hogehoge",
  "algorithm":"hmac-sha-1",
  "expires_in":3600,
  "refresh_token":"8xLOxBtZp8",
  "example_parameter":"example-value"
}
(値は適当です)

リソースアクセスはこの通りです。
Access TokenとSecretからSignatureを作成します。

GET /resource/1 HTTP/1.1
Host: example.com
Authorization: MAC token="SlAV32hkKG",
                   timestamp="137131200",
                   nonce="dj83hs9s",
                   signature="kDZvddkndxvhGRXZhvuDjEWhGeE="
(値は適当です)

はい、こちらは

  • Client Credentialの代わりにToken Credentialがある
  • timestamp,nonce,signatureがある

ということで、現在の2-legged OAuthと呼ばれるものに近い形式になっていることがわかります。
署名など現在と同等のレベルを保ちたい場合には、こちらを利用するほうがよさそうですね。

この両方の方法を検討するにあたり、Access Tokenの有効期限がポイントになりそうです。

Access Tokenの有効期限と使い勝手

簡単に書くとこんな感じですね。

  • Tokenの有効期限が短い=Access Token取得/更新処理が増える≒使いずらい?
  • Tokenの有効期限が長い=1.0のConsumerKey/Secretが2.0だとToken/Secretに代わっただけ?

OpenSocial Containerの人たちはこのあたりどう考えておられるのでしょうか?
OAuth 2.0のMLでこのあたりの話をあまり見かけない気がするのでちょっと気になります。

RSAのSignatureないのか?

あ、そうそう、RSAの方のSignatureを使うパターンは提案されていませんね。
例えばこんなのとかどうでしょう。

  • 1. ClientはToken EndpointからAccess Token + RSA PublicKeyのKeyIdを取得
  • 2. ClientはKeyIdを用いてAuthZ ServerからPublic Keyを取得
  • 3. ClientはPublic Keyを用いてSignatureを作成し、AuthZ Headerにつける

どうでしょう?

まとめ

  • Client CredentialからAccess Tokenを取得する処理が必要になる
  • MAC Tokenを使えばhmac-shaなんとかを用いたSignatureつきのリクエストが送れる
  • Tokenの有効期限についてはちょっと考えどころ
  • RSA Signatureの方は未定義っぽい

こんな感じですかね。
ではまたー!