Reputation: 2189
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:
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:
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
Cannot AAD implement the following approach?
[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 :)!
Upvotes: 2
Views: 762
Reputation: 58743
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/MSALprompt=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.
Upvotes: 2