Autn0 Learn Identityのポイントその2 - OpenID Connect and OAuth2

# はじめに
この記事はAuth0が提供している[Lean Identitiy - OpenID Connect and OAuth2](https://auth0.com/docs/videos/learn-identity/02-oidc-and-oauth)のポイントをまとめています。

# 解説
## シナリオファーストアプローチ
Open ID ConnectやOAuth2は複雑なプロトコルでRFCで厳密な技術仕様が規程されています。それらの技術仕様を全て把握した上で、ApplicationにID機能を実装することは至難の技です。[Lean Identitiy - OpenID Connect and OAuth2](https://auth0.com/docs/videos/learn-identity/02-oidc-and-oauth)ではプロトコルではなく<font color="DarkOrange">実際に起こりうるシナリオに焦点を置いています。</font>

<img src="https://i.imgur.com/qlMJVBt.png" width=70%>

## OAuth2で定義しているRole
OAuth2では主に4つのRoleを定義しています。

- Resource Owner : ユーザ
- Resource Server : APIを含む保護されたリソースを提供するサービス
- Client : リソースを要求するApplication
- Authorization Server : 認可サーバ

<img src="https://i.imgur.com/YIMLBPC.png" width=70%>

## 認可サーバ
認可サーバは、<font color="DarkOrange">認可End Point、Token End Point、Discovery End Point</font>の3つのEnd PointをユーザとApplicationに提供しています。

- 認可EP : ユーザが入力したID/PasswordとIdentity Providerが持っているID/Passwordとの検証に利用される
- Token EP : Applicationのクレデンシャル(ApplicationID/Secrect)と認可コードの検証とTokenの発行に利用される
- Discovery EP : 認可サーバ自身の構成情報の取得に利用される
<img src="https://i.imgur.com/bqNZc1V.png" width=70%>

## 権限の付与方式
Open ID Connect/OAuth2ではApplicationが保護されたリソースにアクセスするために必要な<font color="DarkOrange">Tokenの払い出しフロー</font>を規程しています。Tokenの払い出しフローはApplicationのタイプ(Mobile, Front End, Back End, M2M)によって理想とされるフローが規程されています。

<img src="https://i.imgur.com/Qn8G774.png" width=70%>

## Authorization Code Flow
JavaやPHPのようなBack Endで可動するApplicationは<font color="DarkOrange">閉じられたプライベートな環境</font>で可動するため、Tokenの発行に認可コードとクレデンシャルを利用するAuthorization Code Flowが最適です。クレデンシャルは安全が保証されたServer SideのLocal Storageに保管することが推奨されています。以下、フロー概要です。

1. ユーザがBack End ApplicationでLoginボタンを押す
2. ユーザは認可サーバにリダイレクトされてID/Passwordを入力する
3. 認可サーバは入力されたID/Passwordと認証Database上のID/Passwordを照合して、照合に成功したらBack End Applicationに認可コードを払い出す
4. Back End Applicationは認可サーバから払い出された認可コードと自分のクレデンシャル(Application ID/Secret)を認可サーバに渡し、Acccess Tokenの発行を依頼する
5. 認可サーバはBack End Applicationから受け取った認可コードとクレデンシャルを検証して、検証に成功したらBack End ApplicationにID Token, Access Tokenを払い出す
6. Back End Applicationは認可サーバから払い出されたAccess Tokenを利用して保護されたリソースにアクセスして必要な情報の提供を依頼する
7. 保護されたリソースはBack End Applicationから提示されたAccess Tokenを検証して、検証に成功したら要求されている情報を提供する

<img src="https://i.imgur.com/V5klrgQ.png" width=70%>

## Authorization Code Flow with PKCE
AngularやReactのようなFront End(携帯アプリやブラウザ)で可動するApplicationは<font color="DarkOrange">公共のインターネット環境</font>に存在するため、クレデンシャルを保管する場所を持っていません。また、携帯アプリではカスタマイズされたURLスキーマを使うことが多く、第3者による中間攻撃の的になるケースが多くあります。これらを避けるために、認可コードの要求前に自分自身を証明するCode Vefifierと呼ばれるキーを発行し、認可コード発行要求時にCode Vefifierを認可サーバに送信します。以下、フロー概要です。

1. ユーザがFront End ApplicationでLoginボタンを押す
2. Front End ApplicationはランダムをCode Verifierを作成し、Code Verifierを元にOAuth2.0で規程されているCode Challengeを作成する
3. ユーザは認可サーバにCode Challengeと共にリダイレクトされID/Passwordを入力する
4. 認可サーバは入力されたID/Passwordと認証Database上のID/Passwordを照合して、照合に成功したらCode Challengeを保管しFront End Applicationに認可コードを払い出す
5. Front End Applicationは認可コードとCode Verifierを認可サーバに渡し、Access Tokenの発行を依頼する
6. 認可サーバはFront End Applicationから受け取ったCode VerifierとCode Challengeを照合して、照合に成功したらBack End ApplicationにID Token, Access Tokenを払い出す
7. Back End Applicationは認可サーバから払い出された認可コードと自分のクレデンシャル(Application ID/Secret)を認可サーバに渡し、Acccess Tokenの発行を依頼する
8. 認可サーバはBack End Applicationから受け取った認可コードとクレデンシャルを検証して、検証に成功したらBack End ApplicationにID Token, Access Tokenを払い出す
9. Front End Applicationは認可サーバから払い出されたAccess Tokenを利用して保護されたリソースにアクセスして必要な情報の提供を依頼する
10. 保護されたリソースはFront End Applicationから提示されたAccess Tokenを検証して、検証に成功したら要求されている情報を提供する

<img src="https://i.imgur.com/nHoCINL.png" width=70%>

## Client Credentials Flow
CLIやDaemonのようなMachine 2 Machine Applicationは<font color="DarkOrange">ユーザを介さない、かつ閉じられたプライベートな環境で可動</font>するため、認可サーバに自分自身のクレディンシャル(Application ID/Secret)を渡し直ぐにTokenを受け取ることができます。以下、フロー概要です。

1. M2M Applicationは自分のクレデンシャル(Application ID/Secret)を認可サーバに渡し、Acccess Tokenの発行を依頼する
2. 認可サーバはM2M Applicationから受け取ったクレデンシャルを検証して、検証に成功したらM2M ApplicationにAccess Tokenを払い出す
3. M2M Applicationは認可サーバから払い出されたAccess Tokenを利用して保護されたリソースにアクセスして必要な情報の提供を依頼する
4. 保護されたリソースはM2M Applicationから提示されたAccess Tokenを検証して、検証に成功したら要求されている情報を提供する

<img src="https://i.imgur.com/8LIPyNQ.png" width=70%>

# おわりに
プロトコルや技術仕様詳細に着目し過ぎると本来の目的を見失いがちです。Auth0が提供している[Lean Identitiy - OpenID Connect and OAuth2](https://auth0.com/docs/videos/learn-identity/02-oidc-and-oauth)は実際に起こりうるユースケースやシナリオにフォーカスしており実用性の高い内容を習得することができます。