I've got a Blazor WASM app with .NET 7 and I'm using Azure AD with a public (multi-tenant) app registration. I'm trying to request a scope so that I can authenticate against an API. But it doesn't request include the requested scopes during authentication.
Here is my appsettings.json
:
{
"AzureAd": {
"Authority": "https://login.microsoftonline.com/common",
"ClientId": "[My Balzor app client ID]",
"ValidateAuthority": true,
"Scopes": "openid email profile offline_access api://[My API app client ID]/user_read"
}
}
In Program.cs
I'm configuring this here:
builder.Services.AddMsalAuthentication(options =>
{
builder.Configuration.Bind("AzureAd", options.ProviderOptions.Authentication);
});
I've also tried adding it explicitly:
builder.Services.AddMsalAuthentication(options =>
{
builder.Configuration.Bind("AzureAd", options.ProviderOptions.Authentication);
options.ProviderOptions.AdditionalScopesToConsent.Add("api://[My API app clinet ID]/user_read");
});
However, these scopes are never requested from AAD. The URI only ever includes openid
, profile
, and offline_access
.
Why is my additional scope not requested? How do I fix this?
Your Scopes property is being ignored, because you are binding your "AzureAd" appsettings section to options.ProviderOptions.Authentication
.
And options.ProviderOptions.Authentication
is of type Microsoft.Authentication.WebAssembly.Msal.MsalAuthenticationOptions
which does not include the property DefaultAccessTokenScopes
or Scopes.
The DefaultAccessTokenScopes
property (of type IList
string) is a sibling to the Authentication property on the Microsoft.Authentication.WebAssembly.Msal.Models.MsalProviderOptions
class.
Thus if you restructure your AzureAd section slightly to take into account the MsalProviderOptions
structure, it should all bind correctly without having to call options.ProviderOptions.DefaultAccessTokenScopes.Add()
manually in the Program.cs.
{
"AzureAd": {
"Authentication": {
"Authority": "https://login.microsoftonline.com/common",
"ClientId": "[My Balzor app client ID]",
"ValidateAuthority": "true"
},
"DefaultAccessTokenScopes": ["api://[My API app client ID]/user_read", "..."]
}
}
And then your Program.cs can be updated as follows:
builder.Services.AddMsalAuthentication(options =>
{
builder.Configuration.Bind("AzureAd", options.ProviderOptions);
});