OAuth 2.0 の仕様を読むために


![oauth-2-sm.png](https://qiita-image-store.s3.amazonaws.com/0/6664/2b01df92-7db3-8242-221d-8f0b17b7b90e.png "oauth-2-sm.png")


OAuth 2.0に関しては、いろんな解説や実装がありますが、結局、http://tools.ietf.org/html/rfc6749 にあるRFCの仕様を読むのが一番なのではないかと思い、それを読む際に必要な部分、詰まりやすい部分をまとめてみました。

OAuth 2.0 の公式サイト (http://oauth.net/2/) もRFCは1行で軽くリンクがあるだけで、どうせ皆各言語で実装したライブラリが知りたいんでしょみたいな構成になっていますが、自社もAPIを公開しようとか、マイクロサービスアーキテクチャをしっかり構築しようなどという時に、Resource Server側になることも最近はすごい珍しい訳でも無いのかなと思います。

## 意外とちゃんと訳しておいたほうが良い英単語

例えば、`Authorization=認証`みたいに思っていると意味を誤解しやすいので、きちんと日本語訳の対応付けをしておいたほうがいい英単語はまとめておきました。

| 英語 | 日本語訳 |
| --- | --- |
| Authorization | 権限付与、権限 |
| Grant | 許可証、承認 |
| Credential | 権威の証明証、資格 |

特にAuthorizationは第1義が「権限付与=権限を与える行為」なことに注意しましょう。

> 1. the act of authorizing
> 2. permission or power granted by an authority; sanction.
> 
> http://www.dictionary.com/browse/authorization

これに対し、Grantは、名詞としての第1義が「許可証=承認されたもの」で、第2義が「承認=承認する行為」となっています。

> 1. something granted, as a privilege or right, a sum of money, or a tract of land
> 2. the act of granting.
>
> http://www.dictionary.com/browse/grant

## 4つの役割

[Section 1.1 Roles](http://tools.ietf.org/html/rfc6749#section-1.1)の内容

| 名前 | 役割 | 例 |
| --- | --- | --- |
| Resource Owner | リソースへのアクセス権限を与えられる人またはエンティティ | ユーザー |
| Resource Server | Access Tokenを使ったリソースへのリクエストに応えられるサーバー | FacebookのAPIサーバー |
| Client | 権限に基づき、Resource Ownerの代理としてリソースを要求するアプリケーション（Webアプリでも、PC/モバイルアプリでも） | ユーザーが使っているアプリやサービス |
| Authorization Server | Resource Ownerが認可し権限付与した後、Clientに対し、Access Tokenを発行するサーバー | Facebookの認証サーバー |



### 認証フロー大枠 - 4つの役割の関係性

[Section 1.2 Protocol Flow](http://tools.ietf.org/html/rfc6749#section-1.2)の内容。


OAuth2における流れの大枠は以下のようになる。

```python:Abstract_Protocol_Flow
     +--------+                               +---------------+
     |        |--(A)- Authorization Request ->|   Resource    |
     |        |                               |     Owner     |
     |        |<-(B)-- Authorization Grant ---|               |
     |        |                               +---------------+
     |        |
     |        |                               +---------------+
     |        |--(C)-- Authorization Grant -->| Authorization |
     | Client |                               |     Server    |
     |        |<-(D)----- Access Token -------|               |
     |        |                               +---------------+
     |        |
     |        |                               +---------------+
     |        |--(E)----- Access Token ------>|    Resource   |
     |        |                               |     Server    |
     |        |<-(F)--- Protected Resource ---|               |
     +--------+                               +---------------+

                     Figure 1: Abstract Protocol Flow

```

* A: Clientは、Resource Ownerにリクエストを送る。
 - リクエストは直接行われるか、Authorization Serverを介して行われる
* B: Clientは、Authorization GrantというResource Ownerからの証明証を得る。
 - Clientの種類により、4種類の承認フローのどれにするかを使い分ける必要がある
 - 4つ以外にも、新しい承認フローを仕様に則って作成する事もできる
* C: Clientは、Authorization Serverに、Authorization Grantを見せることで、Access Tokenを要求する。
* D: Authorization Serverは、ClientとAuthorization Grantが正しいことを確認し、正しい場合、Access Tokenを返す。
* E: Clientは、Resource Serverに、Access Tokenとともにリソースを要求する。
* F: Resource Serverは、Access Tokenを検証し、正しかった場合、リクエストの結果を返す。



## 4つの承認フロー

[Section 1.3  Authorization Grant](http://tools.ietf.org/html/rfc6749#section-1.3) と [Section 4 Obtaining Authorization](http://tools.ietf.org/html/rfc6749#section-4)の内容

| 名前 | どんな時に使うか |
| --- | --- |
| [Authorization Code Grant](http://tools.ietf.org/html/rfc6749#section-4.1) | RailsなどバックエンドのサーバーサイドでOAuthする時 |
| [Implicit Grant](http://tools.ietf.org/html/rfc6749#section-4.2) | JavascriptなどWebブラウザのクライアントサイドでOAuthする時 |
| [Resource Owner Password Credentials Grant](http://tools.ietf.org/html/rfc6749#section-4.3) | PCやモバイルアプリなどで、他の方法が使えない環境でOAuthする時 |
| [Client Credentials Grant](http://tools.ietf.org/html/rfc6749#section-4.4) | 社内のAPIサーバー等信頼できるクライアントからOAuthする時 |

### Authorization Code Grant


https://tools.ietf.org/html/rfc6749#section-4.1

```python:Authorization_Code_Flow

     +----------+
     | Resource |
     |   Owner  |
     |          |
     +----------+
          ^
          |
         (B)
     +----|-----+          Client Identifier      +---------------+
     |         -+----(A)-- & Redirection URI ---->|               |
     |  User-   |                                 | Authorization |
     |  Agent  -+----(B)-- User authenticates --->|     Server    |
     |          |                                 |               |
     |         -+----(C)-- Authorization Code ---<|               |
     +-|----|---+                                 +---------------+
       |    |                                         ^      v
      (A)  (C)                                        |      |
       |    |                                         |      |
       ^    v                                         |      |
     +---------+                                      |      |
     |         |>---(D)-- Authorization Code ---------'      |
     |  Client |          & Redirection URI                  |
     |         |                                             |
     |         |<---(E)----- Access Token -------------------'
     +---------+       (w/ Optional Refresh Token)

   Note: The lines illustrating steps (A), (B), and (C) are broken into
   two parts as they pass through the user-agent.

                     Figure 3: Authorization Code Flow


 The flow illustrated in Figure 3 includes the following steps:

   (A)  The client initiates the flow by directing the resource owner's
        user-agent to the authorization endpoint.  The client includes
        its client identifier, requested scope, local state, and a
        redirection URI to which the authorization server will send the
        user-agent back once access is granted (or denied).

   (B)  The authorization server authenticates the resource owner (via
        the user-agent) and establishes whether the resource owner
        grants or denies the client's access request.

   (C)  Assuming the resource owner grants access, the authorization
        server redirects the user-agent back to the client using the
        redirection URI provided earlier (in the request or during
        client registration).  The redirection URI includes an
        authorization code and any local state provided by the client
        earlier.

   (D)  The client requests an access token from the authorization
        server's token endpoint by including the authorization code
        received in the previous step.  When making the request, the
        client authenticates with the authorization server.  The client
        includes the redirection URI used to obtain the authorization
        code for verification.

   (E)  The authorization server authenticates the client, validates the
        authorization code, and ensures that the redirection URI
        received matches the URI used to redirect the client in
        step (C).  If valid, the authorization server responds back with
        an access token and, optionally, a refresh token.

```

### Implecit Grant


```python:Implicit_Grant_Flow

     +----------+
     | Resource |
     |  Owner   |
     |          |
     +----------+
          ^
          |
         (B)
     +----|-----+          Client Identifier     +---------------+
     |         -+----(A)-- & Redirection URI --->|               |
     |  User-   |                                | Authorization |
     |  Agent  -|----(B)-- User authenticates -->|     Server    |
     |          |                                |               |
     |          |<---(C)--- Redirection URI ----<|               |
     |          |          with Access Token     +---------------+
     |          |            in Fragment
     |          |                                +---------------+
     |          |----(D)--- Redirection URI ---->|   Web-Hosted  |
     |          |          without Fragment      |     Client    |
     |          |                                |    Resource   |
     |     (F)  |<---(E)------- Script ---------<|               |
     |          |                                +---------------+
     +-|--------+
       |    |
      (A)  (G) Access Token
       |    |
       ^    v
     +---------+
     |         |
     |  Client |
     |         |
     +---------+

   Note: The lines illustrating steps (A) and (B) are broken into two
   parts as they pass through the user-agent.

                       Figure 4: Implicit Grant Flow


   The flow illustrated in Figure 4 includes the following steps:

   (A)  The client initiates the flow by directing the resource owner's
        user-agent to the authorization endpoint.  The client includes
        its client identifier, requested scope, local state, and a
        redirection URI to which the authorization server will send the
        user-agent back once access is granted (or denied).

   (B)  The authorization server authenticates the resource owner (via
        the user-agent) and establishes whether the resource owner
        grants or denies the client's access request.

   (C)  Assuming the resource owner grants access, the authorization
        server redirects the user-agent back to the client using the
        redirection URI provided earlier.  The redirection URI includes
        the access token in the URI fragment.

   (D)  The user-agent follows the redirection instructions by making a
        request to the web-hosted client resource (which does not
        include the fragment per [RFC2616]).  The user-agent retains the
        fragment information locally.

   (E)  The web-hosted client resource returns a web page (typically an
        HTML document with an embedded script) capable of accessing the
        full redirection URI including the fragment retained by the
        user-agent, and extracting the access token (and other
        parameters) contained in the fragment.

   (F)  The user-agent executes the script provided by the web-hosted
        client resource locally, which extracts the access token.

   (G)  The user-agent passes the access token to the client.

```

### Resource Owner Password Credentials Grant

http://tools.ietf.org/html/rfc6749#section-4.3


```python:Resource_Owner_Password_Credentials_Flow
     +----------+
     | Resource |
     |  Owner   |
     |          |
     +----------+
          v
          |    Resource Owner
         (A) Password Credentials
          |
          v
     +---------+                                  +---------------+
     |         |>--(B)---- Resource Owner ------->|               |
     |         |         Password Credentials     | Authorization |
     | Client  |                                  |     Server    |
     |         |<--(C)---- Access Token ---------<|               |
     |         |    (w/ Optional Refresh Token)   |               |
     +---------+                                  +---------------+

            Figure 5: Resource Owner Password Credentials Flow


   The flow illustrated in Figure 5 includes the following steps:

   (A)  The resource owner provides the client with its username and
        password.

   (B)  The client requests an access token from the authorization
        server's token endpoint by including the credentials received
        from the resource owner.  When making the request, the client
        authenticates with the authorization server.

   (C)  The authorization server authenticates the client and validates
        the resource owner credentials, and if valid, issues an access
        token.
```


### Client Credentials Grant

http://tools.ietf.org/html/rfc6749#section-4.4

```python:Client_Credentials_Flow
     +---------+                                  +---------------+
     |         |                                  |               |
     |         |>--(A)- Client Authentication --->| Authorization |
     | Client  |                                  |     Server    |
     |         |<--(B)---- Access Token ---------<|               |
     |         |                                  |               |
     +---------+                                  +---------------+

                     Figure 6: Client Credentials Flow


   The flow illustrated in Figure 6 includes the following steps:

   (A)  The client authenticates with the authorization server and
        requests an access token from the token endpoint.

   (B)  The authorization server authenticates the client, and if valid,
        issues an access token.
```

### Refresh Token

http://tools.ietf.org/html/rfc6749#section-1.5

```python:Refreshing_an_Expired_Access_Token

  +--------+                                           +---------------+
  |        |--(A)------- Authorization Grant --------->|               |
  |        |                                           |               |
  |        |<-(B)----------- Access Token -------------|               |
  |        |               & Refresh Token             |               |
  |        |                                           |               |
  |        |                            +----------+   |               |
  |        |--(C)---- Access Token ---->|          |   |               |
  |        |                            |          |   |               |
  |        |<-(D)- Protected Resource --| Resource |   | Authorization |
  | Client |                            |  Server  |   |     Server    |
  |        |--(E)---- Access Token ---->|          |   |               |
  |        |                            |          |   |               |
  |        |<-(F)- Invalid Token Error -|          |   |               |
  |        |                            +----------+   |               |
  |        |                                           |               |
  |        |--(G)----------- Refresh Token ----------->|               |
  |        |                                           |               |
  |        |<-(H)----------- Access Token -------------|               |
  +--------+           & Optional Refresh Token        +---------------+

               Figure 2: Refreshing an Expired Access Token

```