I have 2 sets of controllers: internal and external
I have JWT auth on internals and API Key auth on externals.
How do I setup my API to enable Scalar to ask for API key but only for the external controllers?
I have 2 sets of controllers: internal and external
I have JWT auth on internals and API Key auth on externals.
How do I setup my API to enable Scalar to ask for API key but only for the external controllers?
This is how I enabled Scalar to ask for an API Key for the external set of controllers.
Add a ApiKeySecuritySchemeTransformer class to your API project
Apply the above class to AddOpenApi options.
ApiKeySecuritySchemeTransformer.cs
internal sealed class ApiKeySecuritySchemeTransformer(IAuthenticationSchemeProvider authenticationSchemeProvider) : IOpenApiDocumentTransformer
{
public async Task TransformAsync(OpenApiDocument document, OpenApiDocumentTransformerContext context, CancellationToken cancellationToken)
{
var authenticationSchemes = await authenticationSchemeProvider.GetAllSchemesAsync();
if (authenticationSchemes.Any(authScheme => authScheme.Name == "ApiKeyScheme"))
{
var requirements = new Dictionary<string, OpenApiSecurityScheme>
{
["API key"] = new OpenApiSecurityScheme
{
Type = SecuritySchemeType.ApiKey,
Scheme = "ApiKeyScheme",
In = ParameterLocation.Header,
Name = "X-API-KEY"
}
};
document.Components ??= new OpenApiComponents();
document.Components.SecuritySchemes = requirements;
foreach (var operation in document.Paths.Values.SelectMany(path => path.Operations))
{
operation.Value.Security.Add(new OpenApiSecurityRequirement
{
[new OpenApiSecurityScheme
{
Reference = new OpenApiReference
{
Id = "API key",
Type = ReferenceType.SecurityScheme
}
}] = Array.Empty<string>()
});
}
}
}
}
The first "API key" string is what shows in in the Auth drop down in Scalar:
The second "API key" string is what shows in the placeholder text next to Authentication:
options.AddDocumentTransformer<ApiKeySecuritySchemeTransformer>();
For example:
services.AddOpenApi("external", options =>
{
options.AddDocumentTransformer((document, context, _) =>
{
document.Info = new()
{
Title = "Open API V1",
Version = "v1",
Description =
"""
API for creating and managing accounts and users.
Supports JSON responses.
""",
Contact = new()
{
Name = "API Support",
Email = "[email protected]",
Url = new Uri("https://api.example/support")
}
};
return Task.CompletedTask;
});
options.ShouldInclude = (description) => description.RelativePath!.StartsWith("api/external");
options.AddDocumentTransformer<ApiKeySecuritySchemeTransformer>();