IdentityServer4 - modify token at consent - identityserver4

I'm using IdentityServer4 and I have implemented implicit flow using the demo UI. My client is using the consent screen and I have a case where I need to add some additional parameters to the token after consent. In consent controller POST action:
Is there a way to get the current token? I see that there is a state parameter sent to the controller and passed around with each call. Since the token is created after login, I'm guessing IS4 is using this state to keep the token somewhere in memory. Is there a way for me to retrieve it?
How can I modify the token and add additional claims to it at the consent POST action?

In identity server 4 we have a profile service to modify token claims
services.AddProfileService<CustomProfileService>()

Related

Bearer Token authentication and JWT

I've been provided with a REST API which has authentication type bearer (Security Scheme Type: API Key, Header parameter name: Authorization) and which i use to authenticate the user and then fetch other data (i will only create the front end using react).
As a first step the user logs in and i sent his/her username-password to the prementioned REST API and get back an access and a refresh token.
Is anything wrong with storing these 2 tokens in a cookie in order to use them in subsequent requests? How does JWT comes into play regarding these 2 tokens? Is JWT of any use to me in this situation?
There's nothing wrong in storing the tokens in cookies, but if you're planning to have a Single Page Application with React it should be enough to store these tokens in memory. Once the user refreshes the page you can either make them sign in again or perform a silent login in the background to get a new set of tokens. In both cases the session kept on the Authorization Server should kick in and you should get new tokens without the need of user interaction.
Your tokens will be much safer if you don't keep them in cookies.
JWTs are not a requirement for access and refresh tokens. If you don't have to use them I would recommend going with opaque tokens. That said, since you do not have control over the API you might be limited to the format required by the API. If you don't want to be limited by this format you can set up your own gateway which you can use to perform token exchange or introspection and forward requests to the API with proper tokens (something which is called a Phantom Token pattern.
From my understanding of the question, you are using an identity provider which provides you with access token and refresh token for the users. That means it is a authentication as a service REST API at works here.
The REST API requires an authorisation header to be passed along with the username-password to exchange for access token and refresh token for the users. (correct me if I'm wrong) In this case, you might want to keep the authorisation header away from the users (consult the authentication as a service documentation).
You call the REST API with payloads (the user-password) along with headers like this:
Authorization: ACCESS_TOKEN
However the ACCESS_TOKEN is the one provided by the vendor for you to use the REST API. On success call of the REST API, it should return you with a set of access token and refresh token. You can then use this access token and refresh token to safe guard your own API, API that you control to provide service to your users.
The access token and refresh token might just be JWT tokens (again consult the vendor documentation).
Also if you are using an authentication as a service REST API, check the documentation if they provide a client sdk. In that case, it should show you the best practise of handling the access token and refresh token it returned.

ID tokens vs Access tokens in implicit grant flow

I would like some clarification on how to use ID tokens and access tokens in an implicit grant flow.
I have an Angular SPA using MSAL.js for Angular package and a Web API. The API does NOT call any external services, like MSFT Graph. The back end uses role claims from JWT to establish RBAC authorization to our API functionality only.
This doc says:
https://learn.microsoft.com/en-us/azure/active-directory/develop/id-tokens
id_tokens are sent to the client application as part of an OpenID Connect flow. They can be sent along side or instead of an access token, and are used by the client to authenticate the user.
ID Tokens should be used to validate that a user is who they claim to be and get additional useful information about them - it shouldn't be used for authorization in place of an access token.
This doc shows an authentication flow where a web API is called with an ID token instead of an access token:
https://learn.microsoft.com/en-us/azure/active-directory/develop/v2-oauth2-implicit-grant-flow
This sample code sends ID token too (calling own Web API sample):
https://github.com/Azure-Samples/active-directory-javascript-singlepageapp-dotnet-webapi-v2
The sample back end validates ID token audience against Client ID of the app that issued it.
Given our API is the only consumer of tokens, should we use ID tokens or access tokens?
Generally speaking, when securing your API with the Microsoft Identity platform, clients should be using the access token when making API requests, not the ID token.
check this part
It first calls acquireTokenSlient, which gets a token from the cache if available if not
it calls acquireTokenPopUp which will get an acces token for the specific scope, I am not sure if it would open up a popup window or will get a token in the background with hidden iframe. But it would fetch an access token for sure. API can never be accessed with ID token.
check https://learn.microsoft.com/bs-latn-ba/azure/active-directory/develop/scenario-spa-acquire-token for more clarification

Access one SFDC org via token retrieved from another org

I have 2 salesforce orgs that I need to access via API from my Single page application.
The first org should work as my IDP, to authenticate my user (I am planning to use user-agent flow).
When I authenticate to my IDP org, I am getting an access token and an OpenID token. How can I use any of them to access the second org (also via API)?
So far it seems that I can use the ID token from the IDP to get an access token from the SP using the JWT bearer flow. Then use the access token from there onward.
But so far not sure if the ID token itself can be used instead of the access token to invoke the REST API in the SP. I have posted another question about this:
Can I authenticate to and use REST API using an ID token

Can you use Okta REST API to login a user and get SAML2 response back

We have a successful implementation of SSO with Okta as the IdP and an external PHP site as a SP. We are currently utilizing the Okta Sign On Widget which sends our PHP SP a SAML2 Token.
Question is, can we now change from the widget to the API and still get the SAML 2 token on successful login via the API?
So, Since posting this I figured out that - 'yes you can'. I don't know if this is the cleanest/best way but it works and here is how to do it in case anyone else gets stuck looking into this issue...
Already having SAML2 communication working between Okta as IdP and
PHP site as SP.
Create an API access token in Okta.
Use the access token to post a request for a one-time use token from
the API for a specific user you want to login as:
http://developer.okta.com/docs/api/resources/sessions.html
Redirect the user with the retrieved one-time session token to your
App's embed link with the one-time session token:
http://developer.okta.com/docs/examples/session_cookie.html#retrieving-a-session-cookie-by-visiting-an-application-embed-link
This will log the user into Okta to get a proper session we can then
use to send to our PHP end-point to get the SAML2 token we want but
while utilizing the full customization benefits of the API.

OAuth2 grant for interacting between my Angular app and my REST API?

Help me pick the right OAuth2 grant type for my Angular App and my REST API?
UX-wise I want just one login form on my front-end, that would ask for username/pass(no dialog asking for permissions). I think the "Resource Owner(Password) Grant" is the most appropriate for me(since I control front&backend), but I'm not sure how should I handle access token refresh.
Correct me if I wrong about the flow:
When user submits credentials through login form, access token is returned.
I can store this token in LocalStorage to make subsequent Ajax requests with it.
As I understand access tokens should be short-lived. And should be updated with Refresh token. Should the refresh token be returned with the access token after initial login and also stored on the client? If not what is the alternative?
Should there be any session maintained on the server to invoke access token refresh? or I should make calls from front-end to refresh the access token when it is about to expire. But then I need a refresh token on the front-end, right?
As you see there is a mess in my head about refresh token. Would be great to have some clarification or suggestion for another grant implementation.
Backend technology I guess is irrelevant here, but just in case it's Symfony2 with FOSOAuthServerBundle.
When you are calling the TOKEN endpoint (for every grant_type possible) on a OAuth Server, you get an access_token but other information as well (I think there are all here):
{
access_token: // your short-lived token
expires_in: // number of seconds before the access_token is invalid
token_type: // the type of the access_token
scope: // scopes of the access_token
refresh_token: // long-lived token to get a new access_token
}
You need, in my opinion, all these information (maybe the scope is unused, but all others will be used later). You have to store the access_token to ba able to make API calls. After seconds, your access_token will not work anymore. You will need to get a new one. You can either ask the user to log in AGAIN or use the refresh_token.
You will have to call the OAuth Server on the TOKEN endpoint but with a grant_type: refresh_token. You will have to provide the refresh_token from the first request (among other information) and in return you will have the same response as above. In fact, I think you will have to do that every time an access_token is expired. In my opinion, the server side does not know anything about sessions or connected users. It knows about valid and invalid access_token.
This is OAuth. If you don't want to have to refresh everytime, you can make a long-lived access_token (by setting the expires_in), I think this is the only solution that makes sens in an OAuth context.
Do you need some clarification about OAuth in general?

Resources