I am attempting to integrate Azure AD login and Graph API into my angular2 website.
I have successfully implemented an ADAL login and redirect, built around a useful blog post here
From this I retrieved an id_token parameter that my adalservice can access. Currently this is acheived through a simple context.login()
and catching the token in the redirect.
When I use this token to try and access Microsoft Graph, I receive an InvalidAuthenticationToken
response stating Access Token validation failure
.
I'm new to this stuff, so it could be that my call is intrinsically wrong, or that I lack certain permissions in AD, or my app reg lacks permissions. I've seen that I potentially need to request an access token with sufficient scope, yet I can find any examples of this.
Has anyone used this adalService library to obtain tokens for use with Graph API?
The Azure AD authentication Library (ADAL) enables client application developers to easily authenticate users to cloud or on-premises Active Directory (AD), and then obtain access tokens for securing API calls.
ADAL.NET used AuthenticationContext as the representation of your connection to the Security Token Service (STS) or authorization server, through an Authority. MSAL.NET is designed around client applications.
I found a solution to my problem.
I was using the wrong token. I had to acquire a token specifically for Graph API. This meant I would have to first log in and then call this.context.acquireToken()
like below:
this.context.acquireToken("https://graph.microsoft.com", function (error, id_token) {
if (error || !id_token) {
console.log('ADAL error occurred: ' + error);
}
else {
this.graphAccessToken = id_token;
//Call graph API
}
}.bind(this)
);
It seems like it's essential that this process have 2 calls. Maybe someone can shed some light on whether I can immediately obtain a token with scope for the Graph API on login. Perhaps by setting required permissions for the app in Azure AD.
Just to have a clarity for all, updating the end to end solution here again.
In case you do not have the base starter code, refer to this link Adal-JS Tutorial. This post only concerns with the customization involved.
Step 1: Configure the AdalService
(only new code is shown, other methods remain as it is)
export class AdalService {
public get graphAccessToken() {
return sessionStorage[new AppConstants().User_Graph_Token];
}
public retrieveTokenForGraphAPI() {
this.context.acquireToken('https://graph.microsoft.com', function (error, graph_token) {
if (error || !graph_token) {
console.log('ADAL error occurred: ' + error);
} else {
// Store token in sessionStorage
sessionStorage[new AppConstants().User_Graph_Token] = graph_token;
return;
}
}.bind(this)
);
}
}
The code should have existing handlers for id_token callback and corresponding configuration in the routing. If not, please refer to link above for the initial code.
Now the requirement is retrieve the access_token once the id_token is retrieved. The access_token has additional field for "puid" which describes identifier for claims. This will be the step 2.
Step 2: Update LoginComponent
ngOnInit() {
if (!this.adalService.isAuthenticated) {
console.log('LoginComponent::Attempting login via adalService');
this.adalService.login();
} else {
if (this.adalService.accessTokenForGraph == null) {
console.log('LoginComponent::Login valid, attempting graph token retrieval');
this.adalService.retrieveTokenForGraphAPI();
}
}
Now the token is retrieved and stored for later use.
Step 3: Update Routing for 'access_token' callback
Similar to the 'id_token' callback, we need to add additional callback route for the access_token. The callback components will remain same. Their code is as described in the main link. Note that *access_token" endpoint is MS provided, hence be careful not to change the name.
{ path: 'access_token', component: OAuthCallbackComponent, canActivate: [OAuthCallbackHandler] },
{ path: 'id_token', component: OAuthCallbackComponent, canActivate: [OAuthCallbackHandler] }
Step 4: Use the token wherever required
const bearer = this.adalService.graphAccessToken();
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With