error="invalid_token", error_description="The issuer 'https://sts.windows.net/22914068-b6f0-4fee-a0e6-e8df19bb78a1/' is invalid"
Related Issue: https://learn.microsoft.com/en-us/answers/questions/1697294/authentication-fails-when-api-method-is-protected
I am trying to call a protected method on my api and I get the error shown in the title.
Protected API method being called:
[Authorize(AuthenticationSchemes = "AzureAdB2C")]
[HttpGet]
[Route("SecureIdentity")]
[RequiredScope("access_as_user")]
public ActionResult<string> SecureIdentity()
{
return new ActionResult<string>(...));
}
API Auth configuration (this was working for several years exactly as shown here until it stopped because something changed on Azure):
// This configuration is necessary because we are using two jwt handlers - One for user auth, the other for machine-to-machine.
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer("AzureAdB2C", options =>
{
options.Authority = Configuration["AzureAdB2C:Instance"] + Configuration["AzureAdB2C:Domain"] + "/" + Configuration["AzureAdB2C:SignUpSignInPolicyId"] + "/v2.0";
options.Audience = Configuration["AzureAdB2C:ClientId"];
})
.AddMicrosoftIdentityWebApi(Configuration, "AzureAd"); // machine-to-machine
services.AddAuthorization(options =>
{
// The application should only allow tokens which roles claim contains "DaemonAppRole")
options.AddPolicy("DaemonAppRole", policy => policy.RequireRole("DaemonAppRole"));
});
API Azure config:
"AzureAd": {
"Instance": "https://login.microsoftonline.com",
"Domain": "MyDomain.com",
"TenantId": "22914068-b6f0-4fee-a0e6-e8df19bb78a1",
"ClientId": "2063c9dc-d405-45d8-ac06-6e75f60a2ef7"
},
Azure config of calling App:
"AzureAD": {
// Configuration for Client Credentials flow - interaction between WebAPIController in this project and MyDomain.Web
"Instance": "https://login.microsoftonline.com",
"Tenant": "MyDomain.com",
"ClientId": "e00c59f8-332d-4733-a879-8ed3451324c2",
"ClientSecret": "R8c8Q~vI1V8URsuULDYCbkZ",
"CertificateName": "[Or instead of client secret: Enter here the name of a certificate (from the user cert store) as registered with your application]",
"APIBaseAddress": "https://localhost:5010",
"APIScope": "api://2063c9dc-d405-45d8-ac06-6e75f60a2ef7/.default"
},
Calling app httpClient is built as follows:
app = ConfidentialClientApplicationBuilder.Create(config.ClientId)
.WithClientSecret(config.ClientSecret)
.WithAuthority(config.Authority)
.Build();
httpClient = HttpClientFactory.Create(new TokenExpiryHandler(config, app));
httpClient.BaseAddress = new Uri(config.APIBaseAddress);
HttpResponseMessage response = await httpClient.GetAsync("api/status/SecureIdentity");
The API as defined on Azure does have this role defined: "DaemonAppRole"
The API as defined on Azure does have this api exposed: "access_as_user"
The client app as defined on Azure does have api permission: "access_as_user"