OAuth2: Verify Microsoft Account access_token - oauth-2.0

Does anyone know if there is a way to verify a microsoft account access token?
Like the ones for Facebook and Google are verified here: Verify Access Token - Asp.Net Identity

I found it myself. See
Requesting info using REST
on https://msdn.microsoft.com/en-us/library/hh826533.aspx

According to Microsoft documentations :
Access tokens
Currently, access tokens issued by the v2.0 endpoint can be consumed only by Microsoft Services. Your apps shouldn't need to perform any validation or inspection of access tokens for any of the currently supported scenarios. You can treat access tokens as completely opaque. They are just strings that your app can pass to Microsoft in HTTP requests.1
In the near future, the v2.0 endpoint will introduce the ability for your app to receive access tokens from other clients. At that time, the information in this reference topic will be updated with the information that you need for your app to perform access token validation and other similar tasks.
When you request an access token from the v2.0 endpoint, the v2.0 endpoint also returns metadata about the access token for your app to use. This information includes the expiry time of the access token and the scopes for which it is valid. Your app uses this metadata to perform intelligent caching of access tokens without having to parse open the access token itself.
Source : https://learn.microsoft.com/en-us/azure/active-directory/develop/active-directory-v2-tokens
So, currently there is no such endpoint which can allow us to verify access/refresh tokens.

Related

Extending OAuth2 MS AD access_token data

I am missing some understanding of OAuth2 access_token hope someone can explain or guide me to what I am missing.
I am using Microsoft Azure AD as an authentication provider for my application, I used the returned id_token after successful authentication to extend it with some additional data custom to my application (to facilitate authorization).
I am doing this throw JWT.sign, I decode the data from id_token and add data then I sign it using a secret key saved at the server.
My question is, can I do the same for access_token? When I tried to do so, I get unauthorized.
Am I doing something wrong? Or this is not possible? And why is this happening, I don't find any request made to MS to validated my new signed access_token.
You should never change tokens issued - this is not a correct thing to do. But your point about using domain specific claims is totally valid - all real world systems need these for their authorization.
OPTION 1
Some specialist providers can reach out at time of token issuance and contact your APIs, to get domain specific data to include in tokens. See this Curity article for how that works. I don't think Azure AD supports this though.
PRIVACY
It is best to avoid revealing sensitive data in readable tokens returned to internet clients. If you include name, email etc in ID tokens or access tokens this may be flagged up in PEN tests, since it is Personally Identifiable Information and revealing it can conflict with regulations such as GDPR.
Curity recommends protecting access tokens by issuing them in an opaque reference token format - via the phantom token pattern.
OPTION 2
An option that would work fir Azure AD is to adopt the following approaches:
Look up extra domain specific claims in your API when an access token is first received, then cache results for further API requests with the same access token. See this Azure AD Code Sample class of mine for some code that builds a custom ClaimsPrincipal. Note that the API continues to validate the JWT on every request.
If the UI needs extra domain specific claims then serve them from your API, which can return both OAuth User Info and domain specific data from its ClaimsPrincipal to the UI. See this API controller class for how that looks. Personally I always do this and never read ID tokens in UIs - which should also never read access tokens.
Applications interacting with Azure AD, receive ID tokens after authenticating the users. The applications use access tokens and refresh tokens while interacting with APIs.
The id_token is a JSON Web Token (JWT) which has user profile
attributes in the form of claims. The ID Token is consumed by the
application and used to get user information like the user's name,
email.
The Access Token on the otherhand is a credential that can be
used by an application to access an API.
So if you need application to access api, there the access token is used and you may follow the suggestion steps provided by Tiny Wang
Similar to id tokens, access tokens are also signed, but they are not
encrypted. As per IETF OAuth (RFC 6749) standard specification ,
access token can have different formats and structures for each
services whereas, id token should be JWT format.
To validate an id_token or an access_token, your app has to validate
both the token's signature and the claims. To validate access tokens,
your app should also validate the issuer, the audience, and the
signing tokens.
So in production application, you should get id token by specifying
“id_token+code” or “id_token+token” as response_type to verify
whether the authentication is correctly succeeded. It means it uses
the id_token for authentication and “code” to exchange access_token
to access the resource for authorization.
In short id_token is used to identify the authenticated user, and the
access token is used to prove access rights to protected resources.
Refer this for the information regarding access token and id token.

Access Token from OIDC vs OAuth2.0

I know that the access token obtained from OAuth2.0 can be used to access protected resources.
OpenID Connect issues ID token and access token after authentication. And the spec says that the access token can be used to access userinfo endpoint to get additional user information.
One thing I'm not able to understand is, is there any difference between the access token obtained in #1 vs #2. If there is no difference then do we need OAuth2.0, if we implement OIDC.
You tend to just implement both OIDC and OAuth 2.0 together as a combined flow, by plugging in an Open Id Connect security library.
Eg For a mobile app it is common to plug in AppAuth Libraries, which would give you this behaviour:
An OAuth 2.0 authorization redirect using response_type=code
The Open Id Connect part is initiated by including scope=openid
You then get an authorization code (OAuth 2.0)
You then swap the authorization code for tokens
You get an access token (the OAuth 2.0 part)
You also get an id token (the OIDC part)
In practical terms OIDC introduces some standardisation that makes developing UI flows and dealing with access tokens in APIs easier, eg:
Metadata endpoint, to tell us where all the other endpoints live
JWKS endpoint, from which we can get the access token's public key
Typically in my own code I do not use the id token much at all. However, it is best practice to receive one, so that libraries such as AppAuth can make extra verification checks against received tokens.
If it helps, my Message Workflow Blog Post summarises some messages and use of endpoints.
This access tokens have different audiences ("aud" claim): the OAuth 2.0 access token is intended for resource server (i.e. API), and OIDC access token is intended for identity server itself.
As for me, they cannot be used interchangebly, but some examples (e.g. IdentityServer4) do that without checking the "aud" claim.
PS. The single access token can be used for both purposes if both audiences are included:
Each principal intended to process the JWT MUST identify itself with a
value in the audience claim.<...> In the general case, the "aud" value
is an array of case-sensitive strings, each containing a StringOrURI
value.
JWT doc

After getting token using Authorization Code Flow (OAuth 2.0), how can API knows that token sent from front end is valid?

Lets say I have created my own application. We have react front end and RESTful API as backend and we are using Google OAuth for Authorization of our users. Front end is making calls to the APIs. Front end uses Authorization Code Flow of OAuth. After getting access token from Google OAuth server, front end uses this token to make calls to my backend.
Now Malicious user will get my API's URL, other information required for REST API from Chrome Network tab and can call directly to APIs with access token.
Questions:
How will my REST API know from where the request is coming?
Also how it will validate the access token?
Is it possible once User got all information about my REST API, it can call directly with fake access token?
I have look into the diagram for Authorization Code Flow. Below is the link.
https://learn.microsoft.com/en-us/azure/active-directory/develop/v2-app-types
But how will web api validate the token?
Please guide me if I am lacking some information.
Google's OAuth server will issue your front-end a JSON Web Token (JWT). This token is singed by Google private key. Your API needs to:
Obtain Google's public key and
Verify the signature of the JWT.
If that is valid, the token originated from Google. If not, it didn't come from Google or was tampered with.
After this, your API needs to do a few additional checks:
Check the expiration time and see that it's not in the past. This can be found in the exp claim.
Check that the token is not only from Google but for your API. This can be done by looking at the aud (audience) claim and seeing that it's for you.
Check when the token was issued, and ensure that it's not in the future. The issuance time is in the iat claim.
Check that you should start using it already, and there wasn't some sort of embargo on the usage period. This will be indicated in the not-before claim (nbf).
Check that the type of token is an access token (as opposed to an ID token).
(You can find a longer more detailed description in this howto.)
If you do these things, you can be sure that Google issued the token and that it was intended for your API. It does not indicate to your API that the caller was your front-end. The reason is that the token is an "bearer token", meaning the token is bound only to the one that bears or presents it. To ensure that only your app provides the token, you need it to prove possession of a private key. This is not possible when using Google as your token issuer (to my knowledge).
My question is basically how do my rest api validate integrity of the token. I found the link: https://developers.google.com/identity/sign-in/android/backend-auth

Can an Access Token from a Different Issuer be Used for the Microsoft Graph On Behalf of Flow?

I've been following Microsoft's documentation where a client can call a middle tier API using an access token which in turn uses the same access token as an assertion to obtain an access token from Microsoft Graph (the downstream API) to be able to call Graph API's.
My question is, does that access token from the client have to come from Microsoft? If not (for instance, our access tokens come from an on premises Identity Server), how does Microsoft verify the authenticity of the access token from the client?
The access token needs to come from Azure AD. https://learn.microsoft.com/en-us/graph/auth-v2-user
Have a look at the definition of OBO flow
For the middle-tier service to make authenticated requests to the downstream service, it needs to secure an access token from the Microsoft identity platform, on behalf of the user.
I.e. the original token must have come from AAD to be used for exchange for another token.

External API's Calling My API Secured with Azure Active Directory

If I have an API secured with Azure Active Directory, what is the flow when an external API wants to talk to my internal API?
Is this just an API to API call as normal or is this a special circumstance and needs handling a different way?
Is this just an API to API call as normal or is this a special circumstance and needs handling a different way?
The special circumstance may depend on the confidentiality of the resources served by these api(s) and the level of security your application needs. In the end it is an api to api call only.
There are two approaches you can use if Azure Active Directory (AAD) is your Identity Provider for the entire application.
Application Identity with OAuth 2.0 client credentials grant provided by AAD. The calling API makes a request to AAD token endpoint with its client id, client secret (credential) and the application id (the unique id for the callee API) to receive an access token as response. This token is used as Bearer token to call the downstream API. In this approach client id, client secret, application id that are exchanged for an access token, are static values. Some one who has access to these values may find a way to compromise application security (highly unlikely).
The second approach is Delegated User Identity with OAuth 2.0. A request is made to AAD token endpoint with client id, client secret, the access token received as part of calling the tier1 API and a special on_behalf_of parameter to receive an access token, refresh token as response. We preferred this approach as it uses a dynamic value (access token from tier1 api) and also provides a refresh token.
You can read more about these approaches here
If you do not want to use AAD, you can use asp.net built in OwinAuthenticationMiddleware to generate and validate your own access tokens. As said earlier it all depends on your application requirements and implementation details, but in the end it is an API to API call.
Hopefully this is helpful, please let me know if you have any questions.
Thank you,
Soma.
oAuth is done for loggin user to a webservice (see also reference here).
Use OAuth to give your users access to their data while protecting their account credentials.
As another webservice wants to consume one of your service best way to do so is to have another authentication method in order to authorize
Other API, I assume you are talking of machines and not users (alias humans).
So best way is to provide another auth mechanism in order to authorize machines to connect to your API in a safe way.
A simple way to do a machine connection is using a private PKI with public/private key.
A good reference for PKI : http://docs.oracle.com/javase/6/docs/technotes/guides/security/certpath/CertPathProgGuide.html

Resources