# 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}]"}
Expand menu