# JWT Bearer Grant Flow
Public Client 會依據 [RFC-7521 Section 4.1](https://tools.ietf.org/html/rfc7521#section-4.1) 以及 [RFC-7523 Section 2.1](https://tools.ietf.org/html/rfc7523#section-2.1),使用持有的 Authorization Grant 向 [STS](https://en.wikipedia.org/wiki/Security_token_service) 請求 Scoped Access Token。
## Authorization Grant
Public Client 持有的 Authorization Grant 即是透過認可 VIP Session 完成後簽署的 ID Token。
## Client Authentication
Client Authentication 不使用請求自帶的 `client_id` 加 `client_secret`,而是採用由 Client 自簽的 JWT(遵照 [RFC-7521](https://tools.ietf.org/html/rfc7521#section-4.2) 和 [RFC-7523](https://tools.ietf.org/html/rfc7523#section-2.2)),用於 Client 向 Auth Service 作 Token 請求時表明 Client 自己的身分。
這個 JWT 我們稱為 `Client Assertion JWT`,JWT細節請看 [Client Assertion JWT](https://hackmd.io/O3wxLbr9RRaG6Rmzs--H-g#Client-Assertion-JWT)。
## 循序圖
- `Client` 為前端 SPA。
- `AG` 為 Auth Agent。
- `Federation` 為 Auth Agent 上認可 VIP Session 的服務。
- `STS` 為 Auth Service 的 Security Token 服務。
- `RS` 為 Resouce Server。
- Client 持有 ID Token 向 Auth 請求 Access Token。
```sequence
"Client" -> "Federation": "(1) Request federation with\n VIP Session with CFID & CFTOKEN"
"Federation" -> "Federation": "(2) OK"
"Federation" -> "AG": "(3) Response with ID Token"
"AG" -> "STS": "(4) Token Request with ID Token"
"STS" -> "AG" : "(5) Response with Access Token"
"AG" -> "RS": "(6) Resouce Request with Access Token"
"RS" -> "AG": "(7) Resouce Respone"
"AG" -> "Client": "(8) Forward Resouce Respone"
```
1. `Client` 攜帶 `CFID` 與 `CFTOKEN` 向 `Federation` 請求認可 VIP Session。
1. 成功完成後 `Federation`。
1. `Federation` 回應 `ID Token` 給 `AG`
1. `AG` 帶著 `ID Token` 和 grant_type=`urn:ietf:params:oauth:grant-type:jwt-bearer` 向 `STS` 做 Token 交換請求。
1. 通過 Client Authentication 和 ID Token 查驗以及 scope 查驗後,`STS` 回應 `Scoped Access Token` 給 `AG`。
1. `AG` 帶著 `Scoped Access Token` 向 `RS` 做資源請求。
1. `RS` 回應資源請求給 `AG`。
1. `AG` 轉傳回應資源給 `Client`。
## Token 請求參數
| Parameter | Description | Data Tpye | Required |
|----------------------|----------------------------------------------------------------------------------|-----------|----------|
| grant_type | Grant type 必須是 `urn:ietf:params:oauth:grant-type:jwt-bearer` | String | True |
| assertion | 代表 RO 身分的 JWT,即是 ID Token | String | True |
| scope | 請看 [scope](https://hackmd.io/izhz-Ps_T1-Nkm_B2bUTqg#%E5%8F%83%E6%95%B8-scope) | String | False |
| client_assertion_type | client_assertion_type 的類型,必須是 `urn:ietf:params:oauth:client-assertion-type:jwt-bearer` | String | True |
| client_assertion | 用做 Client Authentication,請看 [Client Assertion JWT](https://hackmd.io/O3wxLbr9RRaG6Rmzs--H-g#Client-Assertion-JWT) | String | True |
Client 持有的 ID token 範例如下:
```json
{
"iss": "https://auth.v3.104.com.tw",
"aud": [
"client_id11223344",
"https://auth.v3.104.com.tw"
],
"sub": "pid1234567890",
"exp": 1545382154,
"iat": 1545378554,
"jti": "503a4370-2e30-4f2b-85be-f5b69800f210",
"azp": "client_id11223344",
"nonce": "vPjM6selD1",
"urn:104:v3:entity:pid": "pid1234567890",
"urn:104:v3:entity:company_id": "cid1234567"
}
```
Client Assertion 範例如下:
```json
{
"iss": "client_id11223344",
"aud": "https://auth.v3.104.com.tw",
"sub": "client_id11223344",
"exp": 1545378559,
"iat": 1545378554,
"jti": "f2c1a143-a0ab-4bf8-a8f9-1070e5c90f17",
"pop_cnf": {
"jwk": {
"crv": "P-256",
"kty": "EC",
"x": "dpfPgsekSjAuMegnOttq4vPjM6selD1RWIgywfXru3E",
"y": "KHaq2M8th9-xYlg5HVGHfBwdekVtxor0LA0COHMc8_U"
}
}
}
```
## Token 請求範例
範例:
```http
POST /token HTTP/1.1
Host: auth.vip.104.com.tw
Content-Type: application/x-www-form-urlencoded
Origin: https://vip.104.com.tw
grant_type=urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Ajwt-bearer
&assertion=eyJ0eXAiOiJpZC10b2tlbitqd3QiLCJhbGciOiJFUzI1NiIsImtpZCI6ImM1N2RhMmJiLTUyOWEtNDg4NC1iYWM1LWE4ZTVhYjRmODJmNyJ9.eyJpc3MiOiJodHRwczovL2F1dGgudjMuMTA0LmNvbS50dyIsImF1ZCI6WyJjbGllbnRfaWQxMTIyMzM0NCIsImh0dHBzOi8vYXV0aC52My4xMDQuY29tLnR3Il0sInN1YiI6InBpZDEyMzQ1Njc4OTAiLCJleHAiOjE1NDUzODIxNTQsImlhdCI6MTU0NTM3ODU1NCwiaml0IjoiNTAzYTQzNzAtMmUzMC00ZjJiLTg1YmUtZjViNjk4MDBmMjEwIiwiYXpwIjoiY2xpZW50X2lkMTEyMjMzNDQiLCJub25jZSI6InZQak02c2VsRDEiLCJ1cm46MTA0OnYzOmVudGl0eTpwaWQiOiJwaWQxMjM0NTY3ODkwIiwidXJuOjEwNDp2MzplbnRpdHk6Y29tcGFueV9pZCI6ImNpZDEyMzQ1NjciLCJ1cm46MTA0OnYzOmVudGl0eTpjb21wYW55X2xpc3QiOlsiY2lkMTIzNDU2NyIsImNpZDk4NzY1NDMyMSJdfQ.Pj-gFJT6NFzf2BCCDXcmzFNGx4p3GHr4-53_g0_HRyRGMC6sHOJ22aqzyAyGN6WKQIYag887DzgFSPn4GkXXGw
&client_assertion_type=urn%3Aietf%3Aparams%3Aoauth%3Aclient-assertion-type%3Ajwt-bearer
&client_assertion=eyJ0eXAiOiJjbGllbnQtYXNzZXJ0aW9uK2p3dCIsImFsZyI6IkVTMjU2Iiwia2lkIjoiM2E4ZjIzMWQtNjBmZC00YjJhLTk3MGYtMGQzMjM3Yjg4MzFlIn0.eyJpc3MiOiJjbGllbnRfaWQxMTIyMzM0NCIsImF1ZCI6Imh0dHBzOi8vYXV0aC52My4xMDQuY29tLnR3Iiwic3ViIjoiY2xpZW50X2lkMTEyMjMzNDQiLCJleHAiOjE1NDUzNzg1NTksImlhdCI6MTU0NTM3ODU1NCwiaml0IjoiZjJjMWExNDMtYTBhYi00YmY4LWE4ZjktMTA3MGU1YzkwZjE3IiwicG9wX2NuZiI6eyJqd2siOnsiY3J2IjoiUC0yNTYiLCJrdHkiOiJFQyIsIngiOiJkcGZQZ3Nla1NqQXVNZWduT3R0cTR2UGpNNnNlbEQxUldJZ3l3ZlhydTNFIiwieSI6IktIYXEyTTh0aDkteFlsZzVIVkdIZkJ3ZGVrVnR4b3IwTEEwQ09ITWM4X1UifX19.25zh-5-MKRKNg4OWRvIM6u2AWMneffiNN8Vnw5_A3hb27Fw7CVbPdnSZup9dhZekPoeVoS1DJpv_JXzZbPv7BA
```
## Token 回應範例
範例:
```http-response
HTTP/1.1 200 OK
Content-Type: application/json;charset=UTF-8
Cache-Control: no-store
Pragma: no-cache
Access-Control-Allow-Origin: https://vip.104.com.tw
{
"access_token": "eyJ0eXAiOiJyZXNvdXJjZS1hY2Nlc3MtdG9rZW4rand0IiwiYWxnIjoiRVMyNTYiLCJraWQiOiJjNTdkYTJiYi01MjlhLTQ4ODQtYmFjNS1hOGU1YWI0ZjgyZjcifQ.eyJpc3MiOiJodHRwczovL2F1dGgudjMuMTA0LmNvbS50dyIsImF1ZCI6Imh0dHBzOi8vYXBpLnYzLjEwNC5jb20udHcvZ3JhcGhxbCIsInN1YiI6InBpZDEyMzQ1Njc4OTAiLCJleHAiOjE1NDUzODIxNTQsImlhdCI6MTU0NTM3ODU1NCwiaml0IjoiYmRhMWYwZWEtODc3My00YzA0LWI3MmItOGNkNDZhMGJkOTY2IiwidXJuOjEwNDp2MzplbnRpdHk6cGlkIjoicGlkMTIzNDU2Nzg5MCIsInVybjoxMDQ6djM6ZW50aXR5OmNvbXBhbnlfaWQiOiJjaWQxMjM0NTY3IiwiYXpwIjoiY2xpZW50X2lkMTEyMjMzNDQiLCJzY29wZSI6ImdyYXBocWw6am9iczpyZWFkIGdyYXBocWw6am9iczp3cml0ZSIsImNuZiI6eyJqd2siOnsiY3J2IjoiUC0yNTYiLCJrdHkiOiJFQyIsIngiOiJkcGZQZ3Nla1NqQXVNZWduT3R0cTR2UGpNNnNlbEQxUldJZ3l3ZlhydTNFIiwieSI6IktIYXEyTTh0aDkteFlsZzVIVkdIZkJ3ZGVrVnR4b3IwTEEwQ09ITWM4X1UifX0sImZvcl9vcmlnaW4iOiJodHRwczovL3ZpcC4xMDQuY29tLnR3In0.RUu-BedkqEyOhIKoz9VQLKBRKQGsxy5k2BimG6MnpMzhZhe12tCMizWhrgBlr6zndlFfCQcQAeG5qFGtFwJzQA",
"token_type": "Bearer",
"expires_in": 3600,
"scope": "graphql:jobs:read graphql:jobs:write"
}
```
回應內的 access_token 是 Scoped Access Token,其內容為:
```json
{
"iss": "https://auth.vip.104.com.tw",
"aud": "https://api.vip.104.com.tw/graphql",
"sub": "pid1234567890",
"exp": 1545382154,
"iat": 1545378554,
"jit": "bda1f0ea-8773-4c04-b72b-8cd46a0bd966",
"urn:104:v3:entity:pid": "pid1234567890",
"urn:104:v3:entity:company_id": "cid1234567",
"azp": "client_id11223344",
"scope": "graphql:jobs:read graphql:jobs:write",
"cnf": {
"jwk": {
"crv": "P-256",
"kty": "EC",
"x": "dpfPgsekSjAuMegnOttq4vPjM6selD1RWIgywfXru3E",
"y": "KHaq2M8th9-xYlg5HVGHfBwdekVtxor0LA0COHMc8_U"
}
},
"for_origin": "https://vip.104.com.tw"
}
```
{"metaMigratedAt":"2023-06-14T19:30:23.996Z","metaMigratedFrom":"YAML","title":"JWT Bearer Grant Flow","breaks":true,"robots":"noindex, nofollow","GA":"UA-124732989-1","contributors":"[{\"id\":\"353fecb8-a3ff-45c5-bca5-27a92d73bf5e\",\"add\":1253,\"del\":724},{\"id\":\"533c1e91-5a68-47bd-baba-b33b718f1c11\",\"add\":2,\"del\":2},{\"id\":\"cb532105-71d6-4722-8d3c-210dc68aafeb\",\"add\":19783,\"del\":12939}]"}