InvalidAuthenticationToken. Access token validation failure. Invalid audience - microsoft-graph-api

I am using client credentials flow of OAuth 2.0 client credentials grant. I have given the necessary permission Calendars.ReadWrite in my Azure application, which is needed for the api endpoint 'https://graph.microsoft.com/v1.0/me/events'. I am able to get the token from Servicenow using the api '/{tenant}/oauth2/v2.0/token' and passing the scope as myappURI/.default. But while using the token for the posting an event using the api 'https://graph.microsoft.com/v1.0/me/events' I get 'Code:InvalidAuthenticationToken. Message:Access token validation failure. Invalid audience' error. Any help on this will be much appreciated.

You need to send https://graph.microsoft.com/.default for the scope.
4. Get an access token:
You specify the pre-configured permissions by passing
https://graph.microsoft.com/.default as the value for the scope
parameter in the token request. See the scope parameter description in
the token request below for details.
https://learn.microsoft.com/en-us/graph/auth-v2-service

In my case I was sending the ID Token instead of the Access Token.
ID tokens are meant to be read by the OAuth client.
Access tokens are meant to be read by the resource server.
ID tokens are JWTs. Access tokens can be JWTs but may also be a random string.
ID tokens should never be sent to an API. Access tokens should never be read by the client.
Source: https://oauth.net/id-tokens-vs-access-tokens/

Related

Access tokens and id tokens

I am pretty new with these protocols, and I am having some trouble understanding something.
I am currently working on an application which API and Frontend is mine, I use azure identity platform to receive the tokens on the clientside and send the token to the server that validates the token using passport-azure-ad bearerStrategy. (I have my app registration for that purposes ofcourse).
The thing that I don't get, is that I missed correctly used the tokens I received from azure in my client and sent the ID Token to my API, it verifes it as a valid one and user is authenticated to perform the request sent.
But, as I read here https://learn.microsoft.com/en-us/azure/active-directory/develop/id-tokens, and in any other article about oAuth2 and openID, ID tokens are for UX stuff and client, while I should have used the access token in my request to my API.
But howcome the ID Token is also verified in my API? It makes no sense for me, or am I missing something?
And if so, is there any vurlnabilty in using Id Token as I did?
Thank you!
APIs should first validate the JWT access token, to check these fields have allowed values. An ID token will then fail the audience check.
JWT signature
Not expired / valid at this time
Issuer (a Microsoft ID)
Audience (eg api.mycompany.com)
Access tokens have scopes, whereas ID tokens do not. Every API endpoint should validate the received scope, eg to ensure that it has received the right type of token. This will also ensure that the API does not accept ID tokens.
So although some API tech stacks accept ID tokens, making the standard checks will ensure the right behavior. And the real API authorization is then done using claims, to apply your business rules.

Why RefreshToken received form azure active directory is not in JWT format

I need to understand why refresh token issued by AAD is not in JWT format( i used Auth Code grant type for generation of refresh token). It looks something like as follows 0.ATYAoWHs1YRqUk-OAYpDkwKjaYAEJhrbDpBNmWw7q0NZVas2APk....(rest of the token).
Also if we can get this refresh token in JWT format then how can we do that.
Thanks
Abhishek
It isn't in JWT format because it does not need to be.
A refresh token is data that you send to the identity provider to get new access tokens.
It should not have any other meaning for your application.
Store it securely and send it to AAD when you need new tokens.
Then take the new refresh token you get in the response and overwrite your previous refresh token with that.
The OAuth 2 RFC also talks about it https://www.rfc-editor.org/rfc/rfc6749#page-10:
A refresh token is a string representing the authorization granted to the client by the resource owner. The string is usually opaque to the client. The token denotes an identifier used to retrieve the authorization information. Unlike access tokens, refresh tokens are intended for use only with authorization servers and are never sent to resource servers.

Oath2 open Id connect - How to exchange access_token for a id_token

I am using Forgerock as my identity provider and am looking for something in their rest api where i can provide an access token in the form of a Authorisation Bearer Token and get the corresponding JWT token to use as a Authorisation Bearer Token in a subsequent rest api call.
Can someone help me with what endpoint I can call in Forgerock to do this? I've had a look at the userinfo endpoint, that seems to return what is in the id_token in json format, but I want the actual id_token. A "token exchange".
thanks
There is no endpoint defined by specifications to obtain and ID token for an access token. Specificaitons define about token intrsopection endpoint (RFC7662) and user info endpoint (which you have already figured out).
Other than these, best option is to obtain ID Token from token response itself. For this you need to follow OpenID Connect request format, which include scope value openid. For this, you will require end use consent (most of the time) which allows authorization server to share their claims through id token.
Google Doc says that you can specify response_type for gapi?.auth.authorize
You can use it to get id_token

Against what resource service check bearer/access token?

When a client send a request to resource service with OAuth access token,
how resource service check the access token?. Does resource server validate access token against some entity ?
When resource server get a request with a OAuth access token, it have two options to validate the access token.
First option is to contact token introspection endpoint of the authorization server. This endpoint is a standard endpoint defined by RFC7662 which is a part of OAuth 2.0 specification. According to that spec. resource server can will send a token introspection request to authorization server. If access token is valid (ex:- Not yet expired) then response will contain a active=true state. Please go through RFC7662 to understand how this works.
Second option is to use self contained token. In this approach, authorization server issue JWT based access tokens. Once resource server receive this token, it can go through contents of JWT to identify validity of the access token.
The validation of the token against a specific operation on a specific resource is done using oauth2 scopes
The way the resource server performs the validation itself depends on the implementation, the simplest way is to use "self contained tokens" e.g. JWT ones so you can get the scopes from the token itself without additional lookup.
If your server exposes resources using traditional http REST semantic, the simplest implementation is to use an http middleware / filter which just check the resource uri and the http verb to determine the validity of the operation

Azure AD: Need to validate id_token received with access token?

I'm doing authorization with Azure AD (using /oauth2/v2.0/authorize) with these scopes:
openid email profile https://graph.microsoft.com/user.read
In response, I get an id_token and an authorization code. I ignore this id_token and use the authorization code to get an access token (using /oauth2/v2.0/token)
When I get the access token, I again get an id_token along with it.
The Microsoft docs state:
When your app receives an ID token, it must validate the signature to prove the token's authenticity and validate a few claims in the token to prove its validity.
But since my app received the ID token based on its own HTTPS post to a Microsoft server, is it safe to use the ID token without validating it?
According to what you have described,
You are using OpenID Connect
You are using the hybrid flow (with response_type=code id_token)
If you are not expecting an id token from authorization request, you can use use other either Authorization code flow or Implicit flow
These flow types are selected from response_type parameter and not from claims.
For authorization code flow,
response_type=code
For Implicit flow,
response_type=id_token token or response_type=id_token
Note that, implicit flow does not produce an access token and is intended for JavaScript or similar clients which cannot protect a refresh token.
Once you get the id token from the token endpoint or from authorization endpoint(based on implicit flow), you can validate it just once.

Resources