I've to call a protected API during authorization. The API returns additional information for the user such as roles, groups, permissions ...
Both, the api and the blazor application, are registered in Azure AD B2C. Calling the API works after the authorization process is completed.
If I try to call the api during the event OnTokenValidated
I'll get an error when trying to get a token.
ErrorCode: user_null Microsoft.Identity.Client.MsalUiRequiredException: No account or login hint was passed to the AcquireTokenSilent call.
I've tried to implement the token acquisition like here: https://github.com/AzureAD/microsoft-identity-web/wiki/customization#how-to-query-microsoft-graph-on-token-validated
In Program.cs
builder.Services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme)
.AddMicrosoftIdentityWebApp(options =>
{
builder.Configuration.GetSection("AzureAd").Bind(options);
var prevOnTokenValidatedHandler = options.Events.OnTokenValidated;
options.Events.OnTokenValidated = async context =>
{
await prevOnTokenValidatedHandler(context).ConfigureAwait(false);
await AuthorizationHelper.ValidateAADAppToken(context);
};
}
)
.EnableTokenAcquisitionToCallDownstreamApi()
.AddInMemoryTokenCaches();
In AuthorizationHelper
internal static async Task ValidateAADAppToken(Microsoft.AspNetCore.Authentication.OpenIdConnect.TokenValidatedContext context)
{
ITokenAcquisition ta = context.HttpContext.RequestServices.GetRequiredService<ITokenAcquisition>();
var scopes = new[] { "https://<Tenant>/<ApiId>/access_as_user" };
//var accessToken = await ta.GetAccessTokenForUserAsync(scopes);
var accessToken = Task.Run(() => ta.GetAccessTokenForUserAsync(scopes)).GetAwaiter().GetResult();
HttpClient httpClient = new HttpClient();
httpClient.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", accessToken);
var response = await httpClient.GetAsync("https://localhost:7297/WeatherForecast");
}