问题
So, I am trying to do see if I can support a scenario where a C# daemon app can access a custom Web API protected with MSAL.NET and OAuth2 scopes. As of now, I see no way of doing this.
The versions of the libraries and toolsets are:
.NET Core 2.2 Microsoft.Identity.Client 4.1.0
The client is
var app = ConfidentialClientApplicationBuilder.Create("<app_id_of_my_web_api>")
.WithClientSecret("<client_secret>")
.WithAuthority("https://login.microsoftonline.com/<tenant_id_that_hosts_the_web_api>")
.Build();
and then to acquire token
await app.AcquireTokenForClient(new string[] { "api://<app_id_of_the_web_api>/.default" });
At this point, I do get the token back with which I call my custom Web API end point protected using MSAL and an Azure App with the above mentioned App ID. This doesn't work since I have a policy based authorization on the end point, expecting a specific custom scope defined in the Azure AD app.
The question is, how do I configure the client and Azure AD so I will get the specific scopes passed in as claims for the Web API?
回答1:
You need to register two applications, one for daemon app(client app), one for web api(backend app).
Click the web api app->Expose an API.
Click the daemon app->API permissions->Add a permission->My APIs->choose web api app->select the permissions.
Then the client
var app = ConfidentialClientApplicationBuilder.Create("<client app id>")
.WithClientSecret("<client app client_secret>")
.WithAuthority("https://login.microsoftonline.com/<tenant_id>")
.Build();
The scope:
await app.AcquireTokenForClient(new string[] { "api://<app_id_of_the_web_api>/read" });
Refer to this sample. You can think of your web api as Microsoft Graph API.
回答2:
First of all thanks much, Caiyi, for the pointers. That got me thinking the right way about the approach. Unfortunately, I am forced to use the api:///.default to get an access token. No amount of cajoling seems to work when using a "regular" scope. I configured the apps as was suggested above, but instead of:
await app.AcquireTokenForClient(new string[] { "api://<app_id_of_the_web_api>/read" });
I had to use:
await app.AcquireTokenForClient(new string[] { "api://<app_id_of_the_web_api>/.default" });
In the configuration for the API app, I had to define an "appRole" in the manifest that identifies the role that I was going to assign the Daemon app and then in the Web API, I changed my policy code to check for the scopes OR the app role - which worked.
来源:https://stackoverflow.com/questions/57147646/daemon-apps-and-scopes