Oauth 2.0 | SPA | How does id_token disguise as an access_token for accessing restricted web resources?

Ashokan Sivapragasam

I am working on integrating Azure Active Directory for my Angular SPA (or any Javascript) application. Application has a front-end (built with JavaScript) and a Web API (built with any c# or any server side languages).

For reference, https://github.com/Azure-Samples/active-directory-angularjs-singlepageapp

I know that I configured OAuth 2.0 Implicit Grant in SPA AAD Registration. OAuth 2.0 Implicit Grant is slightly relaxed to let SPA gaining access to web resources tied to SPA AAD Registration by redeeming 'id_token'.

OAuth 2.0 Implicit Grant Protocol:

  1. Reach Azure Auth Endpoint with client_id, resource,.. for id_token
  2. Challenge it with credentials
  3. Get id_token as it is posted back to SPA URI.
  4. Use id_token as bearer token to access the restricted web resources.

SPA works very well with id_token and OAuth 2.0 Implicit Grant Protocol for Internal Web API alone.

Reason why we could not acquire access_token from SPA or JS:

SPA could not send XHR to Azure Token Endpoint as SPA is blocked by CORS Policy of Azure Token Endpoint. So, SPA XHR could not acquire access_token.

But, iFrames implementation of Adal.js can fetch access_token by calling cross-domain web resources.

It looks like this is a special case for SPA alone.

QUESTIONS:

  1. How does AAD determine which web resources that 'id_token' holder can access? By looking up the web resources tied to SPA AAD Registration?

    [OP] Adal.js is responsible for intercepting our post-backs to receive and store tokens like id_token & access_token

  2. Cannot AAD implement the following approach?

    • Redirect to Azure Auth Endpoint with client_id, resource,.. for Auth Code.
    • Acquire Authorization_Code from Azure Auth Endpoint by posting it back to SPA URI.
    • Instead for XHR to Azure Token Endpoint, can't we redirect to Azure Token Endpoint with Auth_Code, client_id, resource,.. to let Azure Token Endpoint post back the access_token back to redirect_uri?

    [OP] Adal.js had other plans to use iFrames to call Cross-domain API (Az Auth Endpoint, in this case) and acquire Access Tokens.

P.S. I need real answers for above questions. This case is now solved :)!

juunas

How does AAD determine which web resources that 'id_token' holder can access? By looking up the web resources tied to SPA AAD Registration?

It doesn't. If your API is configured to accept valid AAD tokens with the audience set to your front-end app's client id, it'll accept the token. This isn't a good pattern though, you should use access tokens to call APIs.

As for your question regarding access tokens, a front-end can acquire access tokens through implicit flow by using a redirect or a hidden iframe. If you use ADAL.js or MSAL.js, they do this for you automatically if you ask for an access token from them.

Essentially they open an iframe that goes to the /authorize endpoint with:

  • response_type=token
  • resource=https%3A%2F%2Fgraph.microsoft.com or scope=https%3A%2F%2Fgraph.microsoft.com%2FUser.Read if using v2/MSAL
  • prompt=none

The last parameter tells AAD to not do a prompt (it's a hidden iframe). If a valid session still exists in the user's browser and consent has been granted for the scopes asked, a token is returned as a redirect to your SPA within the iframe. ADAL/MSAL then can grab the token from the iframe URL as they are running on the same host name.

Because of the way this works, you'll want to check if you are within an iframe when your SPA loads and not render the app at all if it is.

And no, you cannot call the /token endpoint from a JS front-end.

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related

How does Oauth2 (Bearer token) work when getting access_token

OAuth 2 access_token vs OpenId Connect id_token

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

How does a SPA extract access token in OAuth2 implicit flow

Unexpected Response from https://www.googleapis.com/oauth2/v4/token. Not giving "access_token", only "id_token"

How to validate access_token(Azure AD OAuth 2.0) in web API?

Google oauth2 returns no id_token

How can I get an oauth2 access_token using Python

Do OpenID Connect id_token and access_token need to be validated if they are obtained by web server?

spring google oauth2 return no access_token

Oauth2: best practice to keep access_token fresh?

Wrong access_token from AAD with OAuth2 flow

OAUTH access_token TTL

How is the access_token value created in drupal/simple_oauth?

How to "sign in with Google" (id_token) *and* receive a code/access_token for specific scope (for the backend)

How get in Azure access_token from Azure Function app with id_token?

How to add roles claim in access_token , currently it is coming in id_token?

How i can add the calculated fields to access_token / id_token

Asp.net Web Api 2 - how to get access_token from C# code

Auth0 Android - How to renew id_token?

Auth0 /oauth/access_token obtain refresh_token mobile app?

Google Oauth2 verifyIdToken return invalid token signature with valid id_token

Cognito '/oauth2/token' end point not returning 'id_token' for Authorization Code Grant with PKCE

How to verify and renew a JWT id_token during my SPA load?

How to extract user_id from JWT access_token (bshaffer oauth library)

Sending oauth access_token via Restangular

OAuth access_token request -> forbidden

Keycloak: Prohibit issuance of an id_token when using Oauth2/OpenID Connect

id Token vs access_token google login api in web

TOP Ranking

HotTag

Archive