はじめに
この記事はAuth0が提供しているLean Identitiy - OpenID Connect and OAuth2のポイントをまとめています。
解説
シナリオファーストアプローチ
Open ID ConnectやOAuth2は複雑なプロトコルでRFCで厳密な技術仕様が規程されています。それらの技術仕様を全て把握した上で、ApplicationにID機能を実装することは至難の技です。Lean Identitiy - OpenID Connect and OAuth2ではプロトコルではなく実際に起こりうるシナリオに焦点を置いています。

OAuth2で定義しているRole
OAuth2では主に4つのRoleを定義しています。
- Resource Owner : ユーザ
- Resource Server : APIを含む保護されたリソースを提供するサービス
- Client : リソースを要求するApplication
- Authorization Server : 認可サーバ

認可サーバ
認可サーバは、認可End Point、Token End Point、Discovery End Pointの3つのEnd PointをユーザとApplicationに提供しています。
- 認可EP : ユーザが入力したID/PasswordとIdentity Providerが持っているID/Passwordとの検証に利用される
- Token EP : Applicationのクレデンシャル(ApplicationID/Secrect)と認可コードの検証とTokenの発行に利用される
- Discovery EP : 認可サーバ自身の構成情報の取得に利用される

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

Authorization Code Flow
JavaやPHPのようなBack Endで可動するApplicationは閉じられたプライベートな環境で可動するため、Tokenの発行に認可コードとクレデンシャルを利用するAuthorization Code Flowが最適です。クレデンシャルは安全が保証されたServer SideのLocal Storageに保管することが推奨されています。以下、フロー概要です。
- ユーザがBack End ApplicationでLoginボタンを押す
- ユーザは認可サーバにリダイレクトされてID/Passwordを入力する
- 認可サーバは入力されたID/Passwordと認証Database上のID/Passwordを照合して、照合に成功したらBack End Applicationに認可コードを払い出す
- Back End Applicationは認可サーバから払い出された認可コードと自分のクレデンシャル(Application ID/Secret)を認可サーバに渡し、Acccess Tokenの発行を依頼する
- 認可サーバはBack End Applicationから受け取った認可コードとクレデンシャルを検証して、検証に成功したらBack End ApplicationにID Token, Access Tokenを払い出す
- Back End Applicationは認可サーバから払い出されたAccess Tokenを利用して保護されたリソースにアクセスして必要な情報の提供を依頼する
- 保護されたリソースはBack End Applicationから提示されたAccess Tokenを検証して、検証に成功したら要求されている情報を提供する

Authorization Code Flow with PKCE
AngularやReactのようなFront End(携帯アプリやブラウザ)で可動するApplicationは公共のインターネット環境に存在するため、クレデンシャルを保管する場所を持っていません。また、携帯アプリではカスタマイズされたURLスキーマを使うことが多く、第3者による中間攻撃の的になるケースが多くあります。これらを避けるために、認可コードの要求前に自分自身を証明するCode Vefifierと呼ばれるキーを発行し、認可コード発行要求時にCode Vefifierを認可サーバに送信します。以下、フロー概要です。
- ユーザがFront End ApplicationでLoginボタンを押す
- Front End ApplicationはランダムをCode Verifierを作成し、Code Verifierを元にOAuth2.0で規程されているCode Challengeを作成する
- ユーザは認可サーバにCode Challengeと共にリダイレクトされID/Passwordを入力する
- 認可サーバは入力されたID/Passwordと認証Database上のID/Passwordを照合して、照合に成功したらCode Challengeを保管しFront End Applicationに認可コードを払い出す
- Front End Applicationは認可コードとCode Verifierを認可サーバに渡し、Access Tokenの発行を依頼する
- 認可サーバはFront End Applicationから受け取ったCode VerifierとCode Challengeを照合して、照合に成功したらBack End ApplicationにID Token, Access Tokenを払い出す
- Back End Applicationは認可サーバから払い出された認可コードと自分のクレデンシャル(Application ID/Secret)を認可サーバに渡し、Acccess Tokenの発行を依頼する
- 認可サーバはBack End Applicationから受け取った認可コードとクレデンシャルを検証して、検証に成功したらBack End ApplicationにID Token, Access Tokenを払い出す
- Front End Applicationは認可サーバから払い出されたAccess Tokenを利用して保護されたリソースにアクセスして必要な情報の提供を依頼する
- 保護されたリソースはFront End Applicationから提示されたAccess Tokenを検証して、検証に成功したら要求されている情報を提供する

Client Credentials Flow
CLIやDaemonのようなMachine 2 Machine Applicationはユーザを介さない、かつ閉じられたプライベートな環境で可動するため、認可サーバに自分自身のクレディンシャル(Application ID/Secret)を渡し直ぐにTokenを受け取ることができます。以下、フロー概要です。
- M2M Applicationは自分のクレデンシャル(Application ID/Secret)を認可サーバに渡し、Acccess Tokenの発行を依頼する
- 認可サーバはM2M Applicationから受け取ったクレデンシャルを検証して、検証に成功したらM2M ApplicationにAccess Tokenを払い出す
- M2M Applicationは認可サーバから払い出されたAccess Tokenを利用して保護されたリソースにアクセスして必要な情報の提供を依頼する
- 保護されたリソースはM2M Applicationから提示されたAccess Tokenを検証して、検証に成功したら要求されている情報を提供する

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