|
1 | 1 | # id-assertion-authz-node-example
|
2 | 2 |
|
3 |
| -This repo is proof-of-concept example of the proposed [Identity Assertion Authorization Grant](https://datatracker.ietf.org/doc/html/draft-parecki-oauth-identity-assertion-authz-grant) flow. This flow is a subset of the Token Exchange grant which allows identity assertions received by a client via SSO to be exchanged with a trusted Identity Provider for an id-jag token. Such a token can then be exchanged for an access token with the resource authorization server. For for information, watch the explainer video [here](https://www.youtube.com/watch?v=I0vdmg79Ga4). |
| 3 | +This repo is proof-of-concept example of the proposed [Identity Assertion Authorization Grant](https://datatracker.ietf.org/doc/html/draft-parecki-oauth-identity-assertion-authz-grant) flow. This flow is a subset of the Token Exchange grant which allows identity assertions received by a client via SSO to be exchanged with a trusted Identity Provider for an `id-jag` token. Such a token can then be exchanged for an access token with the resource authorization server. For for information, watch the explainer video [here](https://www.youtube.com/watch?v=I0vdmg79Ga4). |
4 | 4 |
|
5 | 5 | <img src="images/id_assertion_authz_grant_flow.gif" alt="gif" width="450"/>
|
6 | 6 |
|
@@ -121,70 +121,6 @@ Running at http://localhost:5001/
|
121 | 121 |
|
122 | 122 | Stop the running node processes in the terminal, and stop the VSCode Dev Container or stop the container in Docker Desktop.
|
123 | 123 |
|
124 |
| -<br /> |
125 |
| -<br /> |
126 |
| - |
127 |
| -## How to integrate |
128 |
| - |
129 |
| -### Requesting App Steps |
130 |
| -This section should outline the best practices: |
131 |
| - * Do not add to login flow |
132 |
| - * Only request when needed |
133 |
| - * Do not store JAGs, Store ID/Refresh, and Access/Refresh |
134 |
| - |
135 |
| -#### Okta Workforce Identity Cloud is your Authorization Server |
136 |
| - |
137 |
| -##### Steps for your App Code |
138 |
| -1. Add this SDK/Library |
139 |
| -1. Map to an authorization code |
140 |
| -1. Cache ID Token AND Refresh token |
141 |
| -1. Create a request |
142 |
| -1. Parse Response |
143 |
| -1. Error handling |
144 |
| - |
145 |
| -#### Okta Customer Identity Cloud is your Authorization Server |
146 |
| - |
147 |
| -##### Steps for your App Code |
148 |
| -1. Add this SDK/Library |
149 |
| -1. Map to an authorization code |
150 |
| -1. Cache ID Token AND Refresh token |
151 |
| -1. Create a request |
152 |
| -1. Parse Response |
153 |
| -1. Error handling |
154 |
| - |
155 |
| -#### You have your own non-Okta Authorization Server |
156 |
| - |
157 |
| -##### Authorization Server Steps |
158 |
| -1. Add this SDK/Library |
159 |
| -2. Add the JAG support to the /token endpoint |
160 |
| - |
161 |
| -##### Steps for your App Code |
162 |
| -1. Add this SDK/Library |
163 |
| -1. Map to an authorization code |
164 |
| -1. Cache ID Token AND Refresh token |
165 |
| -1. Create a request |
166 |
| -1. Parse Response |
167 |
| -1. Error handling |
168 |
| - |
169 |
| - |
170 |
| -### Resource App Steps |
171 |
| -This section should outline the best practices |
172 |
| - |
173 |
| -#### Okta Workforce Identity Cloud is your Authorization Server |
174 |
| -1. Is there anything to do here? |
175 |
| - |
176 |
| -#### Okta Customer Identity Cloud is your Authorization Server |
177 |
| -1. Is there anything to do here? |
178 |
| - |
179 |
| -#### You have a custom Authorization Server |
180 |
| - |
181 |
| -##### Authorization Server Step |
182 |
| -1. Add this SDK/Library |
183 |
| -2. Add the JAG support to the /token endpoint |
184 |
| - |
185 |
| -<br /> |
186 |
| -<br /> |
187 |
| - |
188 | 124 | # Non-VSCode Alternative Option
|
189 | 125 |
|
190 | 126 | Alternative option for users who want to run this application locally without using VSCode Dev Containers.
|
@@ -289,3 +225,51 @@ yarn dlx prisma migrate dev --name <some nice description of the changes you mad
|
289 | 225 | # PREFIX could be, for example, "todo0:"
|
290 | 226 | redis-cli --scan --pattern "<PREFIX>" | xargs redis-cli del
|
291 | 227 | ```
|
| 228 | + |
| 229 | + |
| 230 | +# How to Integrate into an Existing Service |
| 231 | +This section outlines the steps needed to implement ID Assertion Authorization Grant in your existing application. |
| 232 | +There are three actors in this flow, the Identity Provider (IdP), the Requesting Application, and the Resource application. |
| 233 | + |
| 234 | +1. The Identity Provider issues `ID-JAG` tokens, and is the SSO provider for the Requesting and Resource apps for a given user. |
| 235 | + |
| 236 | +1. The **Requesting Application** is the Client application which will make the token exchange request to the IdP, ultimately requesting protected resource access from the Resource Server. |
| 237 | + |
| 238 | +1. The **Resource Application** is the application which owns the protected resources and must issue access tokens to the Requesting Application using the flow. |
| 239 | + |
| 240 | +You app can support this flow as a **Requesting App**, a **Resource App**, or both! We recommend integrating in only on way to get started. The section will also cover best practices based on the architecture of the given apps. |
| 241 | + |
| 242 | +## Requesting App Steps |
| 243 | +The Requesting App is the application that is requesting or querying objects or pulling data from another application. This section describes the specific steps to build the ID Assertion Authorization Grant into the application. The Requesting App must make a separate request to IdP for an `ID-JAG` token for each unique resource the user wants to access. To prevent performance issues, follow these best practices: |
| 244 | + |
| 245 | +> [!TIP] |
| 246 | +> Checkout the Debug Console in the App for detailed views of the requests! |
| 247 | +
|
| 248 | +1. Configure SSO with an IdP which supports this flow. |
| 249 | +1. After the Login SSO flow for a user, store the `id_token` or the `refresh_token` returned from the IdP. These are needed to make the token exchange request. (If the `id_token` expires before you want to make the exchange, use the `refresh_token` to receive a new `id_token`.) |
| 250 | + |
| 251 | +1. When you want to load a resource for a user in your application logic, make a token exchange request to the IdP within the lifetime of the `id_token`. Follow [this code example](https://github.com/oktadev/id-assertion-authz-node-example/blob/2a4068213845f4907c90b40823395b14f5dc20a6/packages/wiki0/src/server/controllers/oidc.ts#L110), and/or see the specifics of the request in Section 5 of the [spec](https://datatracker.ietf.org/doc/html/draft-parecki-oauth-identity-assertion-authz-grant). |
| 252 | + |
| 253 | + |
| 254 | +1. Using the result of the exchange, make an `access_token` request to the authorization server. Follow [this code example](https://github.com/oktadev/id-assertion-authz-node-example/blob/2a4068213845f4907c90b40823395b14f5dc20a6/packages/wiki0/src/server/controllers/oidc.ts#L143), and/or see the specifics of the request in Section 6 of the [spec](https://datatracker.ietf.org/doc/html/draft-parecki-oauth-identity-assertion-authz-grant). |
| 255 | + |
| 256 | +1. Store and use the `access_token` as your normally would with the 3rd party resource server. |
| 257 | + |
| 258 | + |
| 259 | +### Best Practices for Requesting Apps |
| 260 | + 1. **Do not add to login flow**. It is not necessary to preload all the JAG tokens, so it is not necessary to mint all of the possible JAG tokens at the time of login. The side effects can be extended login times for users. |
| 261 | + 1. **Only request when needed**. JAG tokens should be requested at the last responsible moment. JAG tokens are not meant to be long lived. Loading does not need to be bulk loaded and optimized. Trying to optimize the requests for multiple JAG tokens can result in poor performance at scale. |
| 262 | + 1. **Do not store JAG Tokens. Store ID, Access and Refresh Tokens**. JAGs are really short lived. As mentioned earlier, JAGs are passed from Requesting Apps to Resource Apps to exchange for an Access Token to access the Resource App. The Access Token is the valuable artifact to be stored and protected. The JAG token is effectively useless once exchanged, so it should be discarded. |
| 263 | + |
| 264 | + |
| 265 | +## Resource App Steps |
| 266 | + |
| 267 | +The Resource App is the application that owns protected resources normally accessed via OAuth2.0 by Requesting App users. This section describes the specific steps to support the ID Assertion Authorization Grant into the application. The Resource App is responsible for validating `ID-JAG` tokens before issuing OAuth `access_tokens` as it normally would. |
| 268 | + |
| 269 | +> [!TIP] |
| 270 | +> Checkout the Debug Console in the App for detailed views of the requests! |
| 271 | +
|
| 272 | +1. Configure SSO with an IdP which supports this flow. |
| 273 | +1. Modify your Authorization Server logic accept these requests at your OAuth2.0 token endpoint. Seethe specifics of the incoming request in Section 6 of the [spec](https://datatracker.ietf.org/doc/html/draft-parecki-oauth-identity-assertion-authz-grant). |
| 274 | +1. Validate the `ID-JAG` tokens properly before issuing an `access_token` as your normally would. Ensure all validations your authorization makes in regular OAuth2.0 flows also apply to this exhcange when evaluating user atuhorization, such as scope validation. Follow [this code example](id-assertion-authz-node-example/packages/authorization-server/jwt-authorization-grant.js), and/or see the specifics of the processing rules in Section 6.1 of the [spec](https://datatracker.ietf.org/doc/html/draft-parecki-oauth-identity-assertion-authz-grant). |
| 275 | +1. Respond with an access token, as outlined in Section 6.1 of the [spec](https://datatracker.ietf.org/doc/html/draft-parecki-oauth-identity-assertion-authz-grant). |
0 commit comments