Reputation: 8402
The question has been raised a couple times on SO but none of these answers seems to work in my situation.
How do I get the access token from a blazor (server-side) web app?
Blazor server - get AAD access token from current logged in user
Server side Blazor get bearer token
I have a Blazor application (Server-Side) running on .net6
. It is connected to my Azure Active Directory. I can successfully authenticate myself to AAD and get the ClaimsPrincipal
instance.
Here is a excerpt from the Program.cs
file where it sets up the AAD:
[...]
builder.Services
.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme)
.AddMicrosoftIdentityWebApp(builder.Configuration.GetSection("AzureAd"))
;
builder.Services
.Configure<OpenIdConnectOptions>(OpenIdConnectDefaults.AuthenticationScheme, options =>
{
options.SaveTokens = true;
});
[...]
The configuration related to the AzureAd
section contains the following information:
[...]
"AzureAd": {
"Instance": "https://login.microsoftonline.com/",
"Domain": "XXX.com",
"TenantId": "5dXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX",
"ClientId": "26XXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX",
"CallbackPath": "/signin-oidc"
}
[...]
Based on the previous answers, once I get successfully authenticated, the following call in the file _Host.cshtml
should have given me a valid access token but it is not the case in my situation:
Question
Why is the returned access token null
in my Blazor application?
Update 1
I have seen answers using these extra 2 calls in the startup file:
[...]
builder.Services
.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme)
.AddMicrosoftIdentityWebApp(builder.Configuration.GetSection("AzureAd"))
.EnableTokenAcquisitionToCallDownstreamApi(new string[] { "openid" })
.AddInMemoryTokenCaches()
;
I see no changes.
Upvotes: 2
Views: 1240
Reputation: 185
If you want to request a token for your downstream API, TokenAcquisition is the way to go:
using Microsoft.Identity.Web;
//...
string token = await TokenAcquisition.GetAccessTokenForUserAsync(new string[] {apiScope});
Combined with IDownstreamWebApi you don't even have to save the token as a string, it will get assigned when the api is called:
protected readonly IDownstreamWebApi _webApi; // Injected
protected readonly ITokenAcquisition TokenAcquisition; // Injected
// ...
public async Task CallApi(){
await TokenAcquisition.GetAccessTokenForUserAsync(new string[] {apiScope});
var response = await _webApi.CallWebApiForUserAsync("apiName", options => ... );
}
And appsettings structure:
"AzureAd": {
"Instance": "https://login.microsoftonline.com/",
"Domain": "<AD domain>",
"TenantId": "<TenantId>",
"ClientId": "<ClientId of this registered app>",
"CallbackPath": "/signin-oidc",
"SignedOutCallbackPath": "/signout-callback-oidc",
"ClientSecret": "<Secret of registered API>"
},
"API": {
"APIScope": "api://<APIAppID>/access_as_user",
"Scopes": "api://<APIAppID/access_as_user",
"BaseUrl": "https://localhost:7003/"
}
Upvotes: 4