I have a web app where the front-end authenticates using Microsoft Entra and uses the bearer token from that to authenticate with my backend APIs.
I have just removed Swagger / SwaggerUI from my app and replaced it with Microsoft's OpenAPI package and Scalar's ASP.NET package; Swagger wasn't fully functional, so I decided to upgrade and spend the time trying to get things working with the modern alternatives.
Scalar starts up and allows me to view all the backend APIs and send requests, but it doesn't know about the authentication so every request to an authenticated API (there are also a few that allow anonymous requests) returns a 401 response.
Can I configure OpenAPI / Scalar so that it knows which APIs require authentication and to authenticate the user properly allowing me to test my authenticated APIs.
At a previous job someone had configured SwaggerUI to do this, where clicking a couple of buttons would trigger authentication with Entra and then authenticate with the APIs we were testing; however, I don't actually know how they did this. This is the functionality I'd like to achieve through Scalar.
This is a personal (non-commercial) site I'm building for a club I'm a member of, for fun (no payment).
I'm using an ASP.NET Core 9 Web API backend and a Blazor WebAssembly frontend (which does authenticate properly).
I can't find any guides on how to do this, so I'm not sure if it's not possible or just too new to have many guides in general.
Update:
After following the answer by Aaron FC below, I got Scalar authenticating with Entra, but I still get 401 errors with the error Bearer error="invalid_token", error_description="The issuer '(null)' is invalid"
in the header. Disabling the issuer checks, I get Bearer error="invalid_token", error_description="The signature key was not found"
My OpenAPI config is now:
builder.Services.AddOpenApi(options =>
{
options.AddDocumentTransformer((document, context, cancellationToken) =>
{
document.Components ??= new OpenApiComponents();
document.Components.SecuritySchemes.Add("oauth", new OpenApiSecurityScheme
{
Type = SecuritySchemeType.OAuth2,
Flows = new OpenApiOAuthFlows
{
AuthorizationCode = new OpenApiOAuthFlow
{
AuthorizationUrl = new Uri(".0/authorize"),
TokenUrl = new Uri(".0/token"),
Scopes = new Dictionary<string, string>
{
{builder.GetConfiguration("AzureAd:Scopes"), "Data Access"}
},
// To allow Scalar to select PKCE by Default
// valid options are 'SHA-256' | 'plain' | 'no'
Extensions = new Dictionary<string, IOpenApiExtension>()
{
["x-usePkce"] = new OpenApiString("SHA-256")
}
}
}
});
return Task.CompletedTask;
});
});
I have a web app where the front-end authenticates using Microsoft Entra and uses the bearer token from that to authenticate with my backend APIs.
I have just removed Swagger / SwaggerUI from my app and replaced it with Microsoft's OpenAPI package and Scalar's ASP.NET package; Swagger wasn't fully functional, so I decided to upgrade and spend the time trying to get things working with the modern alternatives.
Scalar starts up and allows me to view all the backend APIs and send requests, but it doesn't know about the authentication so every request to an authenticated API (there are also a few that allow anonymous requests) returns a 401 response.
Can I configure OpenAPI / Scalar so that it knows which APIs require authentication and to authenticate the user properly allowing me to test my authenticated APIs.
At a previous job someone had configured SwaggerUI to do this, where clicking a couple of buttons would trigger authentication with Entra and then authenticate with the APIs we were testing; however, I don't actually know how they did this. This is the functionality I'd like to achieve through Scalar.
This is a personal (non-commercial) site I'm building for a club I'm a member of, for fun (no payment).
I'm using an ASP.NET Core 9 Web API backend and a Blazor WebAssembly frontend (which does authenticate properly).
I can't find any guides on how to do this, so I'm not sure if it's not possible or just too new to have many guides in general.
Update:
After following the answer by Aaron FC below, I got Scalar authenticating with Entra, but I still get 401 errors with the error Bearer error="invalid_token", error_description="The issuer '(null)' is invalid"
in the header. Disabling the issuer checks, I get Bearer error="invalid_token", error_description="The signature key was not found"
My OpenAPI config is now:
builder.Services.AddOpenApi(options =>
{
options.AddDocumentTransformer((document, context, cancellationToken) =>
{
document.Components ??= new OpenApiComponents();
document.Components.SecuritySchemes.Add("oauth", new OpenApiSecurityScheme
{
Type = SecuritySchemeType.OAuth2,
Flows = new OpenApiOAuthFlows
{
AuthorizationCode = new OpenApiOAuthFlow
{
AuthorizationUrl = new Uri("https://login.microsoftonline/common/oauth2/v2.0/authorize"),
TokenUrl = new Uri("https://login.microsoftonline/common/oauth2/v2.0/token"),
Scopes = new Dictionary<string, string>
{
{builder.GetConfiguration("AzureAd:Scopes"), "Data Access"}
},
// To allow Scalar to select PKCE by Default
// valid options are 'SHA-256' | 'plain' | 'no'
Extensions = new Dictionary<string, IOpenApiExtension>()
{
["x-usePkce"] = new OpenApiString("SHA-256")
}
}
}
});
return Task.CompletedTask;
});
});
Share
Improve this question
edited 7 hours ago
Mog0
asked Feb 16 at 14:39
Mog0Mog0
2,1273 gold badges25 silver badges48 bronze badges
1 Answer
Reset to default 1I struggled with finding documentation too but eventually came across a few things that pointed me in the right direction (linked below). You have to add a DocumentTransformer
-> SecuritySchema
using the AddOpenApi
options:
Configure Open API
builder.Services.AddOpenApi(o =>
{
o.AddDocumentTransformer((document, _, _) =>
{
document.Components ??= new OpenApiComponents();
document.Components.SecuritySchemes.Add("oauth", new OpenApiSecurityScheme
{
Type = SecuritySchemeType.OAuth2,
Flows = new OpenApiOAuthFlows
{
AuthorizationCode = new OpenApiOAuthFlow
{
AuthorizationUrl = new Uri("<your-app-auth-endpoint>"),
TokenUrl = new Uri("<your-app-token-endpoint>"),
Scopes = new Dictionary<string, string>
{
{"api://<client-id>/data.read", "Read Data"}
},
// To allow Scalar to select PKCE by Default
// valid options are 'SHA-256' | 'plain' | 'no'
Extensions = new Dictionary<string, IOpenApiExtension>()
{
["x-usePkce"] = new OpenApiString("SHA-256")
}
}
}
});
return Task.CompletedTask;
});
});
You can find the authorize/token endpoints by going to your Entra Admin Center -> Applications -> App Registrations -> (Selecting Your App) -> Endpoints (top banner at the time of writing)
and then I used the OAuth 2.0 auth/token endpoints that should look something like:
https://login.microsoftonline/<directory-id>/oauth2/v2.0/authorize
https://login.microsoftonline/<directory-id>/oauth2/v2.0/token
Wire-up Scalar with Defaults:
app.MapScalarApiReference(c =>
{
c.WithOAuth2Authentication(o =>
{
o.ClientId = "<client-id>";
o.Scopes = ["api://<client-id>/data.read"];
});
});
We had to add a scope for our API app registration as using just User.Read
did not work. You can do this by going to your app registration -> Expose an API and then adding a scope that will usually look something like: api://<client-id>/<scope-name>
You'll also want to register the redirect url for your client app registration in Entra as the url of the scalar client. In most cases it's something like https://localhost:<some-port>/scalar/v1
Once this is all configured, you can spin up the Scalar UI. There should be an Authentication
box at the top with an Auth Type
dropdown. You can select oauth
and then ensure PKCE/Scopes are selected and click Authorize
.
Additional Context
We currently have two App Registrations in Entra. One is for our Frontend Angular SPA and the other is for our .NET Web API. The client-id
we used was from the frontend App Registration while the scopes
came from the backend App Registration.
Helpful Docs
Customize OpenAPI Documents
Scalar .NET Integration
IDX10511 Errors
SO Post 1
SO Post 2