# (OpenID Connect Core 1.0) 3.2. Authentication using the Implicit Flow
###### tags: `oauth2/oidc`
担当::@Ras:
[toc]
:::info
ここから
https://openid.net/specs/openid-connect-core-1_0.html#ImplicitFlowAuth
<!-- 既出用語 -->
[ID Token]: https://md.trap.jp/35tZ3jjwSQm0NJq7L-YmGA
[Subject Identifier]: https://md.trap.jp/cFiPV3MSSvCxpX1hmjO8JA#:~:text=%E5%80%8B%E4%BA%BA%E6%83%85%E5%A0%B1-,subject%20identifier,-%E5%8D%98%E7%B4%94%E3%81%AB%20Subject
[Validation]: https://md.trap.jp/cFiPV3MSSvCxpX1hmjO8JA#:~:text=Identifier%20Types%20%E3%81%A7-,validation,-%E3%81%82%E3%82%8B%E3%82%82%E3%81%AE%E3%81%94%E3%81%A8
[Authorization Code Flow]: TODO
[OpenID Provider]: https://md.trap.jp/cFiPV3MSSvCxpX1hmjO8JA#:~:text=%E3%83%97%E3%83%AD%E3%83%88%E3%82%B3%E3%83%AB%E3%81%AE%E3%81%93%E3%81%A8-,openid%20provider(op),-OpenID%20Connect%20%E3%82%92
:::
---
Implicit Flowを使った認可
- 任意のトークンはAuthorization Endpointから返される
- Token Endpointは使わない
- Access Tokenと[ID Token]がクライアントに返される
    - エンドユーザーに公開することもある
- 認可サーバーはクライアント認証を実行しない
## 3.2.1.  Implicit Flow Steps
1. クライアントはリクエストパラメータを含めた認証リクエストを用意する
2. クライアントは認可サーバーにリクエストを送る
3. 認可サーバーはエンドユーザーを認証する
4. (認証が成功したら) 認可サーバーはエンドユーザーの同意・認可を得る
5. 認可サーバーはエンドユーザーをID Tokenとともに送り返す
    - 要求されたらAccess Tokenも付与する
    - :@Ras: send backで送り返すなのか ~~the End-User backでエンドユーザーの同意・認可によって得られた背景情報?~~ なのか自信ない
        > Authorization Server sends the End-User back to the Client with an ID Token and, if requested, an Access Token.
6. クライアントはID Tokenの[Validation]を行い、エンドユーザーの[Subject Identifier]を取得する
## 3.2.2.  Authorization Endpoint
Implicit FlowにおけるAuthorization Endpointは[Authorization Code Flow]とほぼ同じ
相違点をサブセクションで記述
:::info
以下ではImplicit FlowをIF、Authorization Code FlowをACFと呼ぶ
:::
### 3.2.2.1.  Authentication Request
定義はACF参照、IFでは3種類の認証パラメータが以下のように使われる
```plaintext
  GET /authorize?
    response_type=id_token%20token
    &client_id=s6BhdRkqt3
    &redirect_uri=https%3A%2F%2Fclient.example.org%2Fcb
    &scope=openid%20profile
    &state=af0ifjsldkj
    &nonce=n-0S6_WzA2Mj HTTP/1.1
  Host: server.example.com
```
- response_type
    - **REQUIRED**
    - 使用する認可フローを決めるOAuth2.0のResponse Type
    - `id_token token`(スペース繋ぎ)または`id_token`
        - `id_token token`: ID Token & Access Token
        - `id_token`: ID Tokenのみ
        - [OAuth.Response](https://openid.net/specs/oauth-v2-multiple-response-types-1_0.html)で定義されている
    - **IFでは**↑の他にAccess Tokenのみを返す`token`が同じくOAuth.Responseで定義されているが、ID Tokenが必須なOIDCでは使わない
- redirect_uri
    - **REQUIRED**
    - レスポンスが送られるリダイレクトURI
    - [OpenID Provider]のクライアントで事前に登録されたものに完全一致する必要がある
    - **IFでは**http://localhost 以外でhttp schemeを使ってはいけない
- nonce
    - **REQUIRED** (ACFではOPTIONAL)
    - クライアントセッションとID Tokenの関連付けに用いられる文字列
        - replay attackを軽減するのにも用いられる
    - 認証リクエストからID Token(の発行?)までmodifyされない
    - 十分なエントロピーが必要
    - 実装は[15.5.2](https://openid.net/specs/openid-connect-core-1_0.html#NonceNotes)
### 3.2.2.2.  Authentication Request Validation
同様
### 3.2.2.3.  Authorization Server Authenticates End-User
同様
### 3.2.2.4.  Authorization Server Obtains End-User Consent/Authorization
同様
### 3.2.2.5.  Successful Authentication Response
ほぼ同様
**IFでは**全てのレスポンスパラメータがリダイレクトURIのflagmentに付与される
```plaintext
  HTTP/1.1 302 Found
  Location: https://client.example.org/cb#
    access_token=SlAV32hkKG
    &token_type=bearer
    &id_token=eyJ0 ... NiJ9.eyJ1c ... I6IjIifX0.DeWt4Qu ... ZXso
    &expires_in=3600
    &state=af0ifjsldkj
```
**IFでは**`code`パラメータは返さない
- access_token
    - OAuth 2.0 Access Token
    - `response_type`が`id_token`でなければ(`id_token token`ならば)返される
- token_type
    - OAuth 2.0 Token Type value
    - `Bearer`または認可サーバーと決めた値
    - `response_type`が`id_token`でなければ(`id_token token`ならば)返される
- id_token
    - ID Token
    - **REQUIRED**
- state
    - OAuth 2.0 state value
    - 認可リクエストに`state`**パラメータが存在すればREQUIRED**
    - クライアントは認可リクエストの`state`パラメータと等しいか検証しなければならない
- expires_in
    - Access Tokenの期限(レスポンスが生成されてからの秒数)
    - OPTIONAL
### 3.2.2.6.  Authentication Error Response
ほぼ同様
**IFでは**エンドユーザーがリクエストを拒否した or 認証が失敗した場合、認可サーバーはリダイレクトURIのfragmentにエラーを付与して返す
def: [RFC6749](https://openid.net/specs/openid-connect-core-1_0.html#RFC6749)
unless a different Response Mode was specified (わからず)
### 3.2.2.7.  Redirect URI Fragment Handling
fragmentで返すため、クライアントはUser Agentにfragment encoded valuesをパースさせてクライアントのロジックで処理する必要がある
JS実装: [15.5.3](https://openid.net/specs/openid-connect-core-1_0.html#FragmentNotes)
### 3.2.2.8.  Authentication Response Validation
**IFでは**クライアントはレスポンスを以下のようにvalidateする必要がある
- レスポンスがOAuth.Responsesに準拠しているか検証する
- RFC6749のvalidation rulesに従う
- [3.2.2.11](#32211-ID-Token-Validation)のID Token validation rulesに従う
- [3.2.2.9](#3229-Access-Token-Validation)のAccess Token validation rulesに従う
### 3.2.2.9.  Access Token Validation
認可エンドポイントからID Tokenと共に発行されたAccess Tokenをvalidateするために、クライアントは以下のことをするべき (SHOULD)
1. `access_token`パラメータのASCII表現のオクテットをハッシュ化する
    - ID TokenのJOSE Headerの`alg`パラメータに指定された
    - [JSON Web Algorithms](https://openid.net/specs/openid-connect-core-1_0.html#JWA)で定義されたハッシュ化アルゴリズム
    - `alg`==`RS256` -> SHA-256
2. ハッシュの左半分をbase64urlエンコードする
3. ID Tokenの`at_hash`値は2.にマッチしなければならない
    - `at_hash`については[3.2.2.10](#32210-ID-Token)
### 3.2.2.10.  ID Token
**IFでは**追加で以下のClaimが必要
- nonce
    - **REQUIRED**
    - ACFではOPTIONAL
- at_hash
    - `access_token`パラメータのASCII表現のオクテットをハッシュ化し、左半分をbase64url encodeしたもの
    - Access Tokenに対するものなので`response_type`パラメータが`id_token token`のときのみ**REQUIRED**
### 3.2.2.11.  ID Token Validation
**IFでは**ID TokenはACFとほぼ同様の作法でvalidateされる
1. [MUST] クライアントはID Tokenのシグネチャをvalidateする
    - JOSE Headerの`alg`パラメータに指定された[JWS](https://openid.net/specs/openid-connect-core-1_0.html#JWS)に従う
2. [MUST] `nonce`Claimが認可リクエストで送られたものと同じか検証する
    - [SHOULD] クライアントは`nonce`値をreplay attack用に確認する
    - replay attackの検知はクライアント依存