図解 OAuth 2.0：認可フレームワーク RFC 6749

# 随時更新します
6/17：1.4, 6/20：1.8, 6/23：2.1

# 環境や前提条件
　セキュリティ・コーディング実務経験なしの電話系エンジニアが、オープン認可のインターネット標準RFC6749を読み解きました。
　本業では、電話・モバイル系の標準（3GPP）を書いたり読んだりしておりました。
　認証・認可については、モバイル網のAAA（認証・認可・アカウンティング）のインタフェースの仕様書を書いたり、実装のPMをしたことがあります。Diameter (Cx/Sh/Gx/Gy)あたり。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2311625/9d28274e-6b66-2945-9b50-79495ac0f0ef.png)

# 超概要
OAuth 2.0はAuthorization (認可）のフレームワーク。
3rd Partyのアプリが、Webサーバに一時的な（認可）アクセス権を得る。
例：Twitterで認証して、ゲームのスクショをtwitterにUP
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2311625/45139837-5a16-1868-0de0-4cfad63ca47d.png)

# 参考文献
## [1]IPA セキュリティ関連 RFC　
https://www.ipa.go.jp/security/rfc/RFC.html#11
技術毎にRFCがまとめられていて、見やすいです。OpenID & OAuthは3つ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2311625/a1f2ab74-403e-7fa4-f561-0beaaddfbab2.png)

## [2] IETF RFC 6749
RFC6749の原本はこちら
https://datatracker.ietf.org/doc/html/rfc6749

## [3] 認可と認証
まずこれが分からないと、RFC読めない。AuthrizationとAuthenticationの違い
https://dev.classmethod.jp/articles/authentication-and-authorization/

## [4] OAuth 2.0 全フローの図解と動画
パラパラ漫画みたいにまとめてくれていた分かりやすい。
https://qiita.com/TakahikoKawasaki/items/200951e5b5929f840a1f


# 詳細編

## 用語集
OAuth 2.0 ：Autorization(認可）のフレームワーク。
Authentication: AuthN 認証　ID/PASSの組み合わせなどで自分を証明 
Atthrization：AuthZ 認可　アクセス権限を与えること
Credential：　ID/PASS 指紋　顔　などの認証に使うための情報
Access token : OAuth ID/PASSの代わりに使う、一時的な認証の文字列(ASCII文字 数字・大文字小文字・記号)


# Abstract 概要
OAuth 2.0はAutorization(認可）のフレームワーク。
3rd Partyのアプリが、HTTP serviceの一部のアクセス権を得る。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2311625/cdc31224-b2b7-27b0-20a5-2cf0a5cbfce4.png)



# 1. イントロ
今まではCredential(ID/PASS認証等)がないと、制限されたリソースにアクセスできなかった。
なので、3rd partyにもをCredentialを配るのが一般的それだと問題あり。
　・サードパーティが平文のパスワードを保存
　・サードパーティがアクセスできる機関や、リソースを細かく設定できない。
　・オーナーがアクセス権を変えたい時に、サードパーティにパスワードを再発行して伝えないといけない。

OAuthではクライアントは、リソースのオーナのサーバーに、アクセス権をリクエストする。
その時はクレデンシャルではなく、一時的なアクセストークンを使う。
アクセストークンは、
　・スコープ（アクセスできる範囲）
　・ライフタイム（制限時間）
　・その他のパラメータ
を設定できる。


# 1.1　Role (登場エンティティの役割)

## Resource owner
　プロテクト（アクサスが制限された）リソースへのアクセスを許すエンティティ。人の場合はend userという。

## Resource server
 Access tokens(アクセストーク)を使ったリクエストを受けて、リソースへのアクセスを許可。

## Client
　リソースへのアクセスをリクエストするアプリ

## Authorization server
　認証が成功して後に、認可（アクセス許可を与え）る。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2311625/6b7578fb-998b-d811-62a7-217ebb430fbf.png)

# 1.2.  Protocol Flow(動作の流れ)

(A)クライアントはAuthZ（認可）リクエストをオーナーのAuthzサーバに送る。
(B)クライアントはAuthorization grant(許可)を受信する。
　 Grantのタイプは4つある。
(C)クライアントがAccess tokenをリクエストする。その時、Authorization grantも送る。
(D)Authzサーバは、authorization grantを確認して有効なら、Access tokenを発行
(E)クライアントがリソースへのアクセスをリスエスト。Access tokenを使う。
(F)リソースサーパがアクセストークンを検証して、有効ならリソースにアクセスできる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2311625/6c848ab6-34b9-8434-f8dc-c42715b1dae1.png)

# 1.3. Authorization Grant (アクセスの許可を付与)
Authorization Grantにより、AuthZ(認可)を付与する。＝クライアントがアクセストークンを得るためにつかうリクエスト。
付与の種類は4つ、ほかにも拡張がある。（このRFCの範囲外で）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2311625/ebe385b0-3259-1fd7-1c8f-2e29b58830c2.png)
## authorization code
user-agenヘッダで設定されたauthorization serverがオーナーの代わりに、authorization codeを返却する。
// user-agenヘッダは、HTTPとかSIP（電話）でも使われている由緒正しいヘッダです。
## implicit
implicit grant 暗黙の付与。JavaScriptとかで直接アクセストークンを発行する方法。
クライアントの認証はコードに埋め込んだ、Redairection　URIで検証するなど。
## resource owner password credentials
ResourceオーナーのCredential(ID/PASS)をそのままアクセストークンを得るためにクラントモツカウ。クライアントとOwner感が信頼できれば使える。
## client credentials 
オーナー＝クライアントの場合。//詳細が書いてない。
# 1.4. Access token
リソースにアクセスするためのクレデンシャル。
Tokenは、スコープ、期間の情報も追加できる。認可付与したオーナー、リソースサーバに紐づく。
Tokenは文字列なのでtokenのなかに、AuthZの情報(ID/PASS)を含んでもいい。
Resourceサーバから見ると、1つのTokenでAuthZ（認証）を抽象化している(ID/PASSまで面倒見いなくてよい)ので
Tokenに紐づくアクセスのScopの設定と、リソースの有効期間を柔軟に設定できる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2311625/f28d9b16-5e90-5f81-b8d5-5b66b9753d54.png)

# 1.5. Refresh Token
Access tokenが期限切れになった時に使う。Clientが、AuthZ(認可サーバ)に新しいAccces tokenの発行をリクエストする際に使用する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2311625/1a5592eb-89f8-2e21-a961-c81784bef007.png)

# 1.6.  TLS Version
 TLS ver 1.2　この時点で最新。　TLS ver 1.0 広く実装されているので、相互接続性を考えるとこちら。

# 1.7 HTTP Redirections
Resurceオーナは、リクエストに対して、HTTPの302 statas code のuser-agentヘッダで、redirection(接続先)を指定することができる。

# 1.8.  Interoperability
このRFCで規定してないが、必要になるコンポーネントがあるので（例：client registration, authorization server capabilities, endpoint discovery）、相互接続できるように注意して実装しましょう。今後に期待。

# 2.  Client Registration
クライアントのregistration(登録)は、client - authZサーバ間のやり取りは必須ではない。信頼とクライアントのプロパティが分かれば、登録してもOK(Redirect URI, Client type)。3rd partyが発行したアサーションでもOK。
クライアントを登録する際にクライアントは、
　- client typeを決める。(2.1章)
　- クライアント向けのredirection UIRsを提供する
　- その他、authZ serveが求める情報を含める（アプリ名、ウェブサイト等）(3.1.2章)

# 2.1 Client Types
## クライアントにcredentialのセキュリティを担保できるかで2 typeに分類。
・confidential(機密性あり)
　redentialのセキュリティ対策をしており、credentialへの他者のアクセスも制限できる
・public（一般）
　credentialのセキュリティ担保できないクライアント。

## クライアントのタイプ3種類
### web application (type : confidential)
web server上で動くconfidentialなwebアプリ。
リソースオーナーは、HTMLでクライアンとにアクセスする。user-agentの情報をもとにアクセスする。
クライアントのcredentialとaccess tokenは、web server上に保管され、リソースオーナーはアクセスできない。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2311625/9e4c5546-7bb0-5d08-b66b-db25a113ea41.png)

### user-agent-based application (type: public)
Clientコードをwebサーバからダウンロードしブラウザ等で実行。
エンドユーザは、自由にAuthZ(認可の処理）ができる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2311625/a3a679e7-5aee-e00a-a9b0-adae84a8a25e.png)

### native application (public)
　リソースオーナーのdeviceにクライアントをインストールし実行。クレデンシャル(token等)はリソースオーナーからアクセス可能。AuthZ認可の手続きもアプリから自由にできる。
一方、tokenは同じデバイス内の他のアプリからプロテクトされている。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2311625/073a8fc6-eb96-e046-a599-58ffdfa08b1f.png)

# 2.2. Client Identifier
AuthZサーバが、クライアントIDを発行する。Resource ownerに公開されるので、単品では使えない。

# 2.3. Client Authentication
ClientタイプがConfidentialな場合（= web application type）の場合、ClientとAuthZサーバ間で、client AuthN(認証)する。
Confidential typeのclientは、credentiay( IP/PASS, 公開鍵/秘密鍵等）を使てAuthN(認証）する。
Clientタイプがpubllicな場合も、クライアントをAuthN(認証）してもよい[MAY]
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2311625/3e5ae63a-98f7-c74a-796f-5e3369abfe8f.png)

## 2.3.1.  Client Password
Client passwordは、HTTP basic authN（認証）を使ってもよい[MAY]  RFC2617。
Client IDは、"application/x-www-form-urlencoded"にエンコード。

もしくは、AuthN（認証）サーバは、request-bodyに設定sれ他clirent_idとclient_secretをサポートしてもよい。

---
     POST /token HTTP/1.1
     Host: server.example.com
     Content-Type: application/x-www-form-urlencoded

     grant_type=refresh_token&refresh_token=tGzv3JOkF0XG5Qx2TlKWIA
     &client_id=s6BhdRkqt3&client_secret=7Fjfp0ZBr1KtDRbnfVdmIw
---

AuthZ serverはpassword 認証する際はTLSを使う。