I am currently prototyping an authentication model for a series of cloud based micro services and have run into a wall when trying to obtaining a token from Azure AD on behalf of the authenticated user. I feel I am missing something obvious so I am hoping someone can point me in the right direction.
Overview
My prototype consists of two applications:
Both applications are hosted in azure and use Azure's active directory for access management. In azure, I have set up two AD instances:
Both the UI and data service are registered in the service directory and set to multi-tenant. The UI authentication is based on Vibronet's multi-tenant sample and correctly pushes the users through the consent grant flow when they first log in, and then registers the UI application with the users AD instance. During the consent grant, the UI requests the following permissions:
The user is then redirected back to the UI application and I can successfully view the users claim information at this point. So, up until this point I believe everything is configured and working correctly.
The Problem
Once the user is authenticated, the UI application should then obtain a token on behalf of the current user to access the back-end data service and this is where the problem lies.
The authentication for the data service is based on WebApi-On-Behalf-of sample however whenever I attempt to obtain the token, I get the following error:
No permission to access user information is configured for [AppGuid] application, or it is expired or revoked
Given the permissions granted during the consent flow, however, I believe it should have permissions to access the tenant AD instance and have tried giving the UI application all application and delegated permissions available in AD and re-running the consent flow but still get the same result.
My code for obtaining the on-behalf-of token is as follows:
ClientCredential uICredentials = new ClientCredential(StartUp.UiClientId, StartUp.UiSecret);
BootstrapContext bootStrapContext = GetBootstrapContext();
UserAssertion userAssertion = new UserAssertion(bootStrapContext.Token);
AuthenticationContext authContext = new AuthenticationContext(StartUp.adAuthority);
var authResult = authContext.AcquireToken(routerServiceResourceId, uICredentials, userAssertion);
with the exception being raised on the final line. The parameters here are:
In addition, I have set 'SaveSigninToken' to true in the TokenValidationParameters for the UI application so I can obtain the BootstrapContext.Token.
As far as I can see, this is everything it should need to work but, as I say, I continually get the error above =/
Can anyone suggest a way forward / obvious solution / further reading for this. I seem to be banging my head against this and not getting very far. I am also not 100% what information is pertinent here regarding the problem so if I have missed any important points, please let me know and I can update the question.
The OnBehalf of flow isn't really appropriate in this case. The OnBehalf of flow is appropriate when a WebAPI receives an access token and needs to get an access token for a downstream WebAPI. The flow that is most appropriate in your case is the OpenID Connect code+id_token flow. In this flow the WebApp receives an id_token that authenticates the user and an authorization code that allows the WebApp to get an access token for a back end server. The WebApp then redeems the authorization code for the access token.
The best example of this flow is here:
https://github.com/AzureADSamples/WebApp-WebAPI-OpenIDConnect-DotNet
Pay attention to Startup.Auth.cs where the AuthorizationCodeRecieved notification is set up. This shows how to retrieve the code and redeem it.