Reputation: 1465
We have an AppService that runs an AngularJS single page app (WebApp) and an AppService that runs a .Net Service (Service).
WebApp prompts the user to login and acquires a bearer token to be able to make requests to the Service. If I copy the bearer token and use it in Postman I can make direct requests to the Service.
If I try to make a direct request to the Service for the token, I get the prompt that I require a tenant admin consent so all the auth is done through the WebApp AAD registration.
I'm trying to make requests to the service programatically. Instead of using a username and password I've added a client secret in our AAD App registration for the WebApp. Using that secret I can acquire a bearer token with the https://tenant.onmicrosoft.com/Service/.default
scope but I'm a bit confused as that token does not work in PostMan. I think the token is for the WebApp and not the Service and somehow I have to use that to acquire the Service token.
I played around with a simple page that would produce a working token (one that I could use in Postman) though this requires username and password login. The JavaScript code was:
window.config = {
clientId: 'WebApp client id',
tenant: 'Tenant id',
redirectUri: 'http://localhost:3000',
extraQueryParameter: 'nux=1',
popUp: true,
endpoints : {
'prod':
'Service client id'
}
};
var user = authContext.getCachedUser();
if (!user) {
authContext.login();
return;
}
var cachedToken = authContext.getCachedToken(window.config.endpoints.prod);
if (!cachedToken) {
authContext.acquireToken("**Service client id**", function(error, token) {
console.log(error);
console.log('Token:'+token);
});
}
console.log(cachedToken);
var t = document.getElementById("token");
t.innerText = cachedToken;
Running this on localhost:3000 would produce a token usable in Postman.
Now I'm trying to do this programatically using MSAL.net. When running the AcquireTokenForClient
I get a bearer token but it does not work. I don't know how to get the Service token using my WebApp token and AcquireTokenOnBehalfOf
requires users credentials. I also can't acquire the token directly from the Service because I get the Admin consent required error.
result = app.AcquireTokenForClient(scopes)
.ExecuteAsync().Result;
// the token in the result does not work in postman
I think the WebApp AAD App Registration which is the only one with the admin consent - Granted for Tenant
is the one checking if a given user should have access to the app, then if they are allowed, acquires the token for Service on behalf of that user.
Would it be possible to get that token using the Client Secret or do we need to create a dummy user account in AAD which would be shared by all the apps that need to make requests to the Service directly?
Upvotes: 3
Views: 3821
Reputation: 2746
For client credentials (eg secrets), the scopes that you can get are identified in the app registration api permissions as "application permissions" and NOT "delegated permissions" client crendentials flow cannot get delegated permissions flow. also once you give an application permission, you have to click grant for tenant.. if you don't it won't be able to use it. I assume you have an app registration for the API Service, and another app registration for the web app.
In the appreg for the service, you will have to add an app role in the manifest. this will make an application permission appear when you try to add an api permission from web app.
Here's some information about it: https://joonasw.net/view/defining-permissions-and-roles-in-aad
Upvotes: 2