I have a Blazor wasm frontend where I can authenticate myself with an App Registration on Azure. I can successfully login and my identity is correct. In other solution, I have a backend with protected endpoint with [Authorize]
attribute.
[ApiController]
[Route("/")]
public class DummyController : ControllerBase
{
[HttpPost("foo")]
[Authorize]
public IActionResult Foo()
{
return Ok("Foo");
}
}
In my program.cs
of my backend, I have this lines:
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(options =>
{
options.Authority = "https://login.microsoftonline.com/{TENANT-ID}";
//options.Audience = "http://localhost:8092/";
});
I try to call this the /foo
endpoint from my HttpClient in frontend:
// program.cs
builder.Services.AddMsalAuthentication(options =>
{
builder.Configuration.Bind("AzureAd", options.ProviderOptions.Authentication);
options.ProviderOptions.LoginMode = "redirect";
options.ProviderOptions.DefaultAccessTokenScopes
.Add("https://graph.microsoft.com/User.Read");
});
And the client in frontend where I try to call my endpoint:
public class DummyClient(IAccessTokenProviderAccessor accessTokenProviderAccessor)
{
private readonly IAccessTokenProviderAccessor _accessTokenProviderAccessor = accessTokenProviderAccessor;
public async Task<string> FooAsync()
{
var tokenResult = await _accessTokenProviderAccessor.TokenProvider.RequestAccessToken();
if (tokenResult.TryGetToken(out var token))
{
_httpClient.DefaultRequestHeaders.Add("Authorization", "Bearer " + token.Value);
}
var client = new HttpClient();
var response = await _httpClient.GetAsync("http://localhost/foo");
var text = await response.Content.ReadAsStringAsync();
return text;
}
}
But I always get a 401 response, what I'm missing or doing wrong ?
Below are my working codes. With "webapi" template and "blazor WASM standalone template". Both with "microsoft authentication". I think you need set scope for api app registeration in Azure.
webapi
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddMicrosoftIdentityWebApi(options =>
{
builder.Configuration.Bind("AzureAd", options);
// Additional options
options.TokenValidationParameters = new TokenValidationParameters
{
ValidAudience = "https://myb2ctest7.onmicrosoft.com/xxxx"
};
}, options => { builder.Configuration.Bind("AzureAd", options); }
);
wasm
private async Task test()
{
string[] scopes = new string[] { "https://myb2ctest7.onmicrosoft.com/xxxx-xxx-xxxx/access_as_user" };
var tokenResult = await _tokenProvider.RequestAccessToken(new AccessTokenRequestOptions
{
Scopes = scopes
});
var client = new HttpClient();
if (tokenResult.TryGetToken(out var token))
{
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token.Value);
var response = await client.GetAsync("https://localhost:7299/weatherforecast");
if (response.IsSuccessStatusCode)
{
string apiResponse = await response.Content.ReadAsStringAsync();
text1 = await response.Content.ReadAsStringAsync();
}
}
}