Hi
I’ve got as follows
“Client App” - this is a Winforms NET 6.0 desktop application. I’ve used Auth0.OidcClient.Core and built a web-based Auth0 login experience into this app. This works fine. I get an access token on a successful login, and a refresh token which my code uses to do a refresh and get a replacement access token at regular intervals.
“Api A” - this is an ASP NET Core 6.0 Web API which I have deployed to Azure. This uses the Microsoft.AspNetCore.Authentication.JwtBearer. The configuration code is shown below. This API is registered in Auth0 and I can use my Client App token to call the API. So far, so good.
Now I have created “Api B” and this is where the problem begins. I want to use my Client App access token to call both Api A and Api B. Api B is, like Api A, an ASP NET Core 6.0 Web API, and both APIs are configured to use JwtBearer authentication. Across both APIs, controllers have the [Authorize] attribute, but nothing more (no authentication “Policy”, for example).
I have reviewed this article, which appears to specifically address my scenario: Configure Logical API for Multiple APIs
So, I have taken the following steps:
-
Registered API B in Auth0
-
Registered a new logical API, let’s call it “API L”, in Auth0
-
As I have no existing Scopes, but the article says I need them to support this scenario, I created new scopes as follows
-In the Permissions tab for API A, I created a new permission called “api:APIA”, intended to represent permission to access API A and all its actions and resources
-In the Permissions tab for API B, I created a new permission called “api:APIB”, intended to represent permission to access API B and all its actions and resources
-In the Permissions tab for API L, I created a new permission called “api:APIA”, matching the above
-In the Permissions tab for API L, I created a new permission called “api:APIB”, matching the above
- Modified my client code to send a login request with the audience for “API L”, and with the new Scopes “api:APIA api:APIB” included in the request.
I found the section of the article which talks about Scopes to be unclear. However My working assumption is that because I now have scopes in API L (“api:APIA”, “api:APIB”) which have identical names to the scopes declared for each of API A (“api:APIA”) and API B (“api:APIB”), Auth0 will then do the necessary magic that allows a token issued for the Logical API to be used to access the other two APIs.
I have not changed the Audience and Domain configuration on the ASP/Azure side of API A or API B. I presume I shouldn’t need to do so in order to make this work.
However, now, API A will not authorise a token issued to my Client App. It returns an “Unauthorised” error.
I am trying to work out what I’m missing.
I did wonder if the fact that the token includes any scope at all (whereas in my previous configuration, there were no scopes defined) might be enough to prevent my API A from authenticating successfully, without making some kind of configuration change to the API. Perhaps I have to instruct the API explicitly to disregard Scopes?
To be clear, I don’t need scopes at all. I just want my client to be able to authenticate to both APIs, using the same token, to access the full functionality of both APIs. However my presumption is that the scopes are necessary to create the magic glue between a “logical api” and a set of concrete APIs.
I would appreciate any pointers here about what i might be doing wrong??
Config code for API A
var builder = WebApplication.CreateBuilder(args);
var GoogleTextSpeechApiKey = builder.Configuration[“GoogleTextSpeech:apikey”];
builder.Services.AddAuthentication(options =>
{
options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
}).AddJwtBearer(options =>
{
options.Authority = $“https://{builder.Configuration[“Auth0:Domain”]}/”;
options.Audience = builder.Configuration[“Auth0:Audience”];
options.TokenValidationParameters = new TokenValidationParameters
{
NameClaimType = ClaimTypes.NameIdentifier
};
});builder.Services.AddControllers();
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();var app = builder.Build();
if (app.Environment.IsDevelopment())
{
app.UseSwagger();
app.UseSwaggerUI();
}app.UseHttpsRedirection();
app.UseAuthentication();
app.UseAuthorization();app.MapControllers();
app.Run();