# (OpenID Connect Core 1.0) 11.Offline Access - 14. String Operations
###### tags: `oauth2/oidc`
担当::@kyosu:
[toc]
https://openid.net/specs/openid-connect-core-1_0.html#OfflineAccess
## 11.Offline Access
OpenID Connect では、offline access を要求するため以下の scope 値を定義している。
- offline_access
- OPTIONAL。OAuth 2.0 Refresh Token の発行を要求する。Refresh Token は End-User の関与を必要とせずに End-User の UserInfo Endpoint にアクセスするための Access Token を取得するために利用される。
offline access を要求する際には、リクエストするリソースに対する offline access の許可に必要な何らかの他の条件を満たさない限り、prompt パラメータに consent を指定しなければならない (**MUST**)。OP は Refresh Token を発行する際は必ず明示的な同意を得なければならない (**MUST**)。ユーザーの事前同意は offline access の許可には常に十分とはならない。
offline_access scope を受け取った Authorization Server は以下に従う。
- prompt パラメータが consent を含むことを確認する
- offline access 要求処理における何らかの他の条件を満たす場合はその限りではない。上記の条件のどちらをも満たさない場合、offline_access リクエストを無視しなければならない (**MUST**)。
- Client が Authorization Code を返すような response_type を指定しない場合、その offline_access を無視しなければならない (**MUST**)。
- Client の登録した application_type が web の場合は, 明示的に同意を得なければならない (**MUST**)。
- Client の登録した application_type が native の場合でも, 明示的な同意を得るべきである (**SHOULD**)。
:::info
application_type は clientのmetadataの一つ。
参考
- https://openid.net/specs/openid-connect-registration-1_0.html#ClientMetadata
:::
Refresh Token の利用は, offline_access がもたらすユースケースのみに限らない。Authorization Server は異なるコンテキストにおいて Refresh Token を発行しても良い (**MAY**)。なおそのようなコンテキストについては、本仕様の定めるところではない。
## 12. Using Refresh Tokens
Refresh Token を利用するには、[OAuth 2.0 [RFC6749] Section 6](https://datatracker.ietf.org/doc/html/rfc6749#section-6) に従い, Token Endpoint に grant_type を refresh_token としたリクエストを送る。ここでは OpenID Connect Authorization Server が Refresh Token を受け取った際の挙動について定義する。
:::info
なお、implicite flow では Refresh Token の発行がサポートされない。(implicite flow はブラウザベースのアプリケーションでの利用が想定されるが、長期的な認証情報を安全に保管することが困難であるため。)
:::
## 12.1. Refresh Request
Access Token 再発行のため、Client は自身の client_id に紐づいて登録された認証方法で、Token Endpoint に対して自身を認証しなければならない (**MUST**)。詳細は Section 9 参照。Client は Section 13.2 で述べる Form Serialization を用いて、Token Endpoint に HTTP POST リクエストを送る。
以下は Refresh Request の例
```
POST /token HTTP/1.1
Host: server.example.com
Content-Type: application/x-www-form-urlencoded
client_id=s6BhdRkqt3
&client_secret=some_secret12345
&grant_type=refresh_token
&refresh_token=8xLOxBtZp8
&scope=openid%20profile
```
Authorization Server は Refresh Token を検証し、それが Client に対して発行されたものであることを確認し、Client 認証がその Client の Client Authentication 方法によって成功したことを確認しなければならない (**MUST**)。
## 12.2. Successful Refresh Response
Refresh Token の検証が成功すると、レスポンスボディに [Section 3.1.3.3](https://openid.net/specs/openid-connect-core-1_0.html#TokenResponse) で述べた Token Response を含める。ただしこのレスポンスは id_token を含まない場合もある。
トークン再発行の際に ID Token を発行する場合は、以下に従う。
- `iss` Claim Value は、最初の認可発生時に発行された ID Token と同じ値にすること (**MUST**)。
- `sub` Claim Value も同様に, 最初の認可発生時に発行された ID Token と同じ値にすること (**MUST**)。
- `iat` Claim は新しい ID Token の発行時刻にすること (**MUST**)。
- `aud` Claim Value は、最初の認可発生時に発行された ID Token と同じ値にすること (**MUST**)。
- ID Token に auth_time Claim を含める場合は、新しい ID Token の発行時刻ではなく、最初の認証を行った時刻とすること (**MUST**)。
- `azp` Claim Value は、最初の認可発生時に発行された ID Token と同じ値にすること (*MUST*)。azp が最初に発行された ID Token に含まれない場合は、新しい ID Token にもそれを含めてはならない (**MUST NOT**)。
- それ以外に関しては、最初の認証時に発行された ID Token と同じルールを適用する。
以下は Refresh Response の例
```
HTTP/1.1 200 OK
Content-Type: application/json
Cache-Control: no-store
Pragma: no-cache
{
"access_token": "TlBN45jURg",
"token_type": "Bearer",
"refresh_token": "9yNOxJtZa5",
"expires_in": 3600
}
```
## 12.3. Refresh Error Response
Refresh Request が不正もしくは認証できなかった場合、Authorization Server は [OAuth 2.0 [RFC6749] Section 5.2](https://datatracker.ietf.org/doc/html/rfc6749#section-5.2) に従い Token Error Response を返す。
## 13. Serializations
メッセージは以下のいずれかの方法でシリアライズされる。
- Query String Serialization
- Form Serialization
- JSON Serialization
ここではこれらのシリアライゼーション方法のシンタックスについて記述する。それらがいつ利用可能、もしくは利用する必要があるかを記述するのは、他セクションに委ねる。すべてのシリアライゼーションがすべてのメッセージに利用可能ではないことに注意すること。
### 13.1. Query String Serialization
Query String Serialization を使ってパラメータをシリアライズするためには、Client は [W3C.REC‑html401‑19991224] で定義された application/x-www-form-urlencoded フォーマットを使いパラメータと値を URL のクエリコンポーネントへ追加することで文字列を構成する。Query String Serialization は一般的に HTTP GET リクエストで使用される。
:::info
https://www.w3.org/TR/html401/interact/forms.html#h-17.13.4.1
:::
以下はシリアライズの参考例
```
GET /authorize?
response_type=code
&scope=openid
&client_id=s6BhdRkqt3
&redirect_uri=https%3A%2F%2Fclient.example.org%2Fcb HTTP/1.1
Host: server.example.com
```
### 13.2. Form Serialization
パラメータやその値は, HTTP リクエストのエンティティボディに [W3C.REC‑html401‑19991224] に定義されているように application/x-www-form-urlencoded フォーマットでパラメータ名とその値を追加することで Form Serialize される。 Form Serialization は一般的には HTTP POST リクエストで利用される。
以下はシリアライズの参考例
```
POST /authorize HTTP/1.1
Host: server.example.com
Content-Type: application/x-www-form-urlencoded
response_type=code
&scope=openid
&client_id=s6BhdRkqt3
&redirect_uri=https%3A%2F%2Fclient.example.org%2Fcb
```
### 13.3. JSON Serialization
パラメータは各パラメータを JSON オブジェクトの最上位メンバーに追加する形で、JSON オブジェクトにシリアライズされる。パラメータ名と文字列値は JSON 文字列として表現される。数値は JSON 数値、Boolean 値は JSON 真偽値となる。他で特別に指示されない限り、省略されているパラメータおよび値が指定されていないパラメータは省略し、JSON null としないようにすべきである (**SHOULD**)。各パラメータは JSON オブジェクトおよび JSON 配列をその値とすることができる (**MAY**)。
以下はシリアライズの参考例
```
{
"access_token": "SlAV32hkKG",
"token_type": "Bearer",
"expires_in": 3600,
"refresh_token": "8xLOxBtZp8"
}
```
## 14. String Operations
いくつかの OpenID Connect メッセージを処理する際にはメッセージの中の値を既知の値を比較することが求められる。例えば, UserInfo エンドポイントから返された Claim Name は sub などの特定の Claim Name と比較される。よって Unicode 文字列比較処理はセキュリティ上重要な意味を持つ。
したがって, JSON 文字列を他の Unicode 文字列と比較する際は下記の通り実施しなければならない (**MUST**)。
1. JSON に適用されたすべてのエスケープ処理を取り除き Unicode コードポイントの配列を生成する。
2. Unicode Normalization [USA15] を JSON 文字列、もしくは比較対象文字列に対していかなる時点であっても適用してはならない (**MUST NOT**)。
3. 二つの文字列の比較は、Unicode コードポイント同士の等値比較として実施されなければならない (**MUST**)。
:::info
UNICODE NORMALIZATION FORMS について
https://unicode.org/reports/tr15/
:::
いくつかの箇所において、本仕様はスペースで区切られた文字列のリストを使用している。そのようないかなる場合においても、この目的では単一の ASCII のスペース文字 (0x20) を区切り文字として使用しなければならない (**MUST**)。
:::info
例えば scope パラメータなどはスペース文字を手区切り文字として利用している。
:::