asp.net-coreopenapiapi-keyscalar.net-9.0

How do I enable Scalar to ask for an API Key in .Net 9?


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?


Solution

  • This is how I enabled Scalar to ask for an API Key for the external set of controllers.

    1. Add a ApiKeySecuritySchemeTransformer class to your API project

    2. Apply the above class to AddOpenApi options.

    3. 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: enter image description here

    The second "API key" string is what shows in the placeholder text next to Authentication: enter image description here

    1. Add this line to options of AddOpenApi 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 = "api@example.com",
                     Url = new Uri("https://api.example.com/support")
                 }
             };
    
             return Task.CompletedTask;
         });
    
         options.ShouldInclude = (description) => description.RelativePath!.StartsWith("api/external");
         options.AddDocumentTransformer<ApiKeySecuritySchemeTransformer>();