Here is my repo: https://github.com/FlameWolf/DotNet9WebApi
My Program.cs
:
public class Program
{
public static void Main(string[] args)
{
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddControllers();
builder.Services.AddOpenApi(options =>
{
options.OpenApiVersion = Microsoft.OpenApi.OpenApiSpecVersion.OpenApi3_0;
});
builder.Services.AddSwaggerGen(options =>
{
options.AddSecurityDefinition("bearerAuth", new()
{
Type = SecuritySchemeType.Http,
In = ParameterLocation.Header,
Scheme = "Bearer",
BearerFormat = "JWT",
Name = "Authorization",
Description = "Enter your bearer token"
});
options.AddSecurityRequirement(new()
{
{
new()
{
Reference = new()
{
Type = ReferenceType.SecurityScheme,
Id = "bearerAuth"
}
},
Array.Empty<string>()
}
});
});
var app = builder.Build();
if (app.Environment.IsDevelopment())
{
app.MapOpenApi();
app.UseSwaggerUI(options =>
{
options.SwaggerEndpoint("/openapi/v1.json", "v1");
});
app.MapGet("/", async context =>
{
await Task.Run(() => context.Response.Redirect("./swagger/index.html", permanent: false));
});
}
app.UseHttpsRedirection();
app.UseAuthorization();
app.MapControllers();
app.Run();
}
}
The same call to AddSwaggerGen
used to work with .NET 8, where we had AddEndpointsApiExplorer
instead of AddOpenApi
, and UseSwagger
instead of MapOpenApi
. A big, beautiful "Authorize" button would be available in the Swagger UI. But now it doesn't. How can I fix this?
You can use document transformers like below:
1.Be sure install the package Microsoft.AspNetCore.Authentication.JwtBearer
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="9.0.0" />
<PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="9.0.0" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="7.0.0" />
</ItemGroup>
2.Update your Program.cs
like below
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.OpenApi;
using Microsoft.OpenApi.Models;
namespace DotNet9WebApi;
public class Program
{
public static void Main(string[] args)
{
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddControllers();
builder.Services.AddAuthentication().AddJwtBearer();
builder.Services.AddOpenApi(options =>
{
options.AddDocumentTransformer<BearerSecuritySchemeTransformer>();
options.OpenApiVersion = Microsoft.OpenApi.OpenApiSpecVersion.OpenApi3_0;
});
var app = builder.Build();
if (app.Environment.IsDevelopment())
{
app.MapOpenApi();
app.UseSwaggerUI(options =>
{
options.SwaggerEndpoint("/openapi/v1.json", "v1");
});
app.MapGet("/", async context =>
{
await Task.Run(() => context.Response.Redirect("./swagger/index.html", permanent: false));
});
}
app.UseHttpsRedirection();
app.UseAuthorization();
app.MapControllers();
app.Run();
}
}
internal sealed class BearerSecuritySchemeTransformer(IAuthenticationSchemeProvider authenticationSchemeProvider) : IOpenApiDocumentTransformer
{
public async Task TransformAsync(OpenApiDocument document, OpenApiDocumentTransformerContext context, CancellationToken cancellationToken)
{
var authenticationSchemes = await authenticationSchemeProvider.GetAllSchemesAsync();
if (authenticationSchemes.Any(authScheme => authScheme.Name == "Bearer"))
{
var requirements = new Dictionary<string, OpenApiSecurityScheme>
{
["Bearer"] = new OpenApiSecurityScheme
{
Type = SecuritySchemeType.Http,
Scheme = "bearer", // "bearer" refers to the header name here
In = ParameterLocation.Header,
BearerFormat = "Json Web Token"
}
};
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 = "Bearer", Type = ReferenceType.SecurityScheme } }] = Array.Empty<string>()
});
}
}
}
}
Reference: Use document transformers