Is it possible to use the an access token requested by another API endpoint to MS Graph to another API endpoint?
Scenario:
API Endpoint A requested an access token and receive the access token and store it to the database.
API Endpoint B used the access token being stored in the database by
API EndPoint A.
NO!
A token can only correspond to one api. The access token is issued according to the api audience you want to access, and it is unique! A token can only have one aud, and you cannot use multiple scopes to request access tokens. If you need to access other api endpoint, you should obtain a token for each api endpoint separately.
Your idea is indeed feasible for some of the same types of api endpoints. For example, if two identical MS Graph APIs endpoint have the same permissions and user role requirements, you can indeed use API A's access token to call API B, but for security reasons, I don't recommend you to do this.
Related
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.
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
I am a newbie to Azure AD. What is the best practice for using Azure AD access tokens?
What is the difference between an 0Auth and JWT token and which one should I use to follow best practices?
I used the below code to get the Token. Do I need to convert it to an 0Auth Token?
var AzureData = await DependencyService.Get<IAuthenticator>()
.Authenticate(App.tenanturl, App.GraphResourceUri, App.ApplicationID, App.ReturnUri);
App.AuthenticationResult = AzureData;
var userToken = Azuredata.AccessToken;
Please help. Thanks.
JWT is a type of Token, and OAuth is a Framework.
JWT (JSON Web Tokens) is just a token format, it defines a compact and self-contained mechanism for transmitting data between parties in a way that can be verified and trusted because it is digitally signed.
Oauth is an authentication framework, where it has a general procedures and setups defined by framework. JWT can be used as a mechanism inside OAuth. You do not need to convert your token.
Use JWT when...
Federation is desired. For example, you want to use Azure AD as the token issuer, and then use Apigee Edge as the token validator. With JWT, an app can authenticate to Azure AD, receive a token, and then present that token to Apigee Edge to be verified. (Same works with Google Sign-In. Or Paypal. Or Salesforce.com. etc)
Asynchrony is required. For example, you want the client to send in a request, and then store that request somewhere, to be acted on by a separate system "later". That separate system will not have a synchronous connection to the client, and it may not have a direct connection to a central token dispensary. a JWT can be read by the asynchronous processing system to determine whether the work item can and should be fulfilled at that later time. This is, in a way, related to the Federation idea above. Be careful here, though: JWT expire. If the queue holding the work item does not get processed within the lifetime of the JWT, then the claims should no longer be trusted.
Use OAuth when...
There is no federation. The issuer of the token is the same party that validates the token. All API requests bearing the token will go through the token dispensary.
There is no need or desire to allow the holder of the token to examine the claims within the token.
When you wish to unilaterally allow token revocation. It is not possible to revoke JWT. They expire when they are marked to expire at creation time.
See this thread for more details.
Does not having a secret defined for an IdentityServer4 API Resource introduce a security vulnerability?
I'm a little confused on the Introspection Endpoint, when it is used, and whether or not someone could use the Introspection endpoint to bypass Authorization and access an API without a defined secret (by a POST with just the API name as a parameter).
Is this possible? Or is the introspection endpoint only authorized through defined clients that use something like the Client Credential Grant?
The introspection endpoint will only validate a posted token, it shouldn't accept an API name in its request.
It can be used to validate reference tokens (or JWTs if the consumer does not have support for appropriate JWT or cryptographic libraries). The introspection endpoint requires authentication using a scope secret.
http://docs.identityserver.io/en/release/endpoints/introspection.html
This shouldn't be an endpoint you need to implement, it is included by identity server in the same way as the '.well-known/openid-configuration'.
A use case for this endpoint would be an API being passed a token and wanting to confirm its genuine and still valid (not expired or revoked), the response would include the claims associated with the token (users claims with the tokens scope taken into consideration)
For introspection security considerations see the RFC 7662 Section 4
An API Resource requires a Client Secret when you are using the Authorization Code Flow as its sending claims on the back channel.
If you are using Reference tokens you will also require a Client Secret, as the access token is never presented to the client, but instead the reference token is passed from the client to the api resource, and then onto the identity server in exchange for the access token.
It really depends on the client and the flow.
I am following this example https://github.com/Azure-Samples/active-directory-dotnet-native-headless to authenticate user against Azure AD using user credentials (uname,pwd) to acquire a bearer access Token. This token will be sent in the Authorization header to the Rest API. The REST API uses the token to authorize the user using ClaimPrincipal.
Now, in my Rest API, I would want to validate if the user belongs to particular Security Group or not. For that purpose I need to use Graph API. But the problem is, every-time I pass the same Bearer Token to my Graph API, which the REST API has received from Client, it throws "Access Token Malformed" error.
In one of the sample (https://github.com/Azure-Samples/active-directory-dotnet-webapi-onbehalfof/blob/master/TodoListService/Controllers/TodoListController.cs) I found we need to regenerate a new Bearer Token to call Graph API, so do I need to re-generate a new Token to call Graph API? Couldn't I use the same Bearer Token which the client has send to my REST API, to call the Graph API?
Tokens are like bank checks. A check written for you can only be cashed by you. If you want to call the graph from your web API, you can use the token you received as a starting point for getting a new token specifically for the graph. See https://azure.microsoft.com/en-us/documentation/samples/active-directory-dotnet-webapi-onbehalfof/ for the pattern used in this case, you just need to substitute the custom API with the graph.