I have a Single Page Application which communicates with a backend REST API. This REST API is made specifically to serve the SPA. In order to navigate or use any functionality of the SPA beyond the home page, users must log in first. I am using OIDC with Okta to authenticate users. Users can either have an Admin role, or a User role. Their role will be used to authorize which SPA pages they are allowed to navigate to, and which REST API calls they are allowed to make.
After a user logs in, my application receives an ID token and and Access token from Okta. I have the option for including the user's role as a custom claim in either the ID token, or the Access token. Which token should include this information in? Both?
The UI needs to make some authorization decisions based on the user role. For example, which HTML elements to show or hide, and which SPA routes are navigatable. Should these decisions be made by inspecting the ID token, or the Access token? Other?
When calling my backend API via the SPA should I forward the ID token and Access token that my SPA received? Just the Access token? Or should I set up a different authorization server for my backend REST API, and have my SPA reach out for another access token?
Some answers:
The id token is just an assertion to the SPA that the user is authenticated. If you are going to put the role in a token, use the access token, whose purpose is authorization
The API should be controlling authorization. Your SPA should ask your API, about authorized areas and the API can answer based on the access token contents. Your SPA should not read the access token directly.
Only send the access token to the API, which is the standard recommended behaviour
RESPONSIBILITIES
Generally:
If you want to use role information in both UI and API, then a default option is to add the role to both the id token and the access token.
However, this does not scale well, since in a real business app you are likely to add multiple similar rules over time, and keep needing to add claims to tokens.
EXTENSIBILITY
A better option that is easier to manage over time, is for the UI to ask its API for the role + other data - since the API needs the same role information anyway.
Also, tokens do not need to be the only source of data for authorization decisions made by UIs and APIs. My blog post on claims describes a pattern you can use to manage claims over time from multiple data sources.