无法向www.example.com核心中的swagger API文档添加授权asp.net

5gfr0r5j  于 2023-03-18  发布在  .NET
关注(0)|答案(1)|浏览(141)

我有一个asp.netcore6项目设置为多个API版本。但是,当我打开nswager api文档时。右边的授权按钮根本不显示。我不确定我错过了什么。
下面是我的代码片段:

public static IServiceCollection AddSwaggerTest(this IServiceCollection serviceCollection, string apiName)
        {
            serviceCollection.AddApiVersioning(opt =>
            {
                opt.DefaultApiVersion = new Microsoft.AspNetCore.Mvc.ApiVersion(1, 0);
                opt.AssumeDefaultVersionWhenUnspecified = true;
                opt.ReportApiVersions = true;
                opt.ApiVersionReader = ApiVersionReader.Combine(new UrlSegmentApiVersionReader(),
                                                                new HeaderApiVersionReader("x-api-version"),
                                                                new MediaTypeApiVersionReader("x-api-version"));
            })
            .AddVersionedApiExplorer(setup =>
            {
                setup.GroupNameFormat = "'v'VVV";
                setup.SubstituteApiVersionInUrl = true;
            })
            .AddSwaggerGen(option =>
            {
                option.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme
                {
                    In = ParameterLocation.Header,
                    Description = "Please enter a valid token",
                    Name = "Authorization",
                    Type = SecuritySchemeType.Http,
                    BearerFormat = "JWT",
                    Scheme = "Bearer"
                });

                option.AddSecurityRequirement(new OpenApiSecurityRequirement
                {
                    {
                        new OpenApiSecurityScheme
                        {
                            Reference = new OpenApiReference
                            {
                                Type=ReferenceType.SecurityScheme,
                                Id="Bearer"
                            }
                        },
                        new string[]{}
                    }
                });

                option.EnableAnnotations();
                option.CustomSchemaIds(x => x.FullName);

                var provider = serviceCollection.BuildServiceProvider().GetRequiredService<IApiVersionDescriptionProvider>();

                foreach (var description in provider.ApiVersionDescriptions)
                {
                    var xmlPath = Path.Combine(AppContext.BaseDirectory, $"{apiName}.xml");

                    if (File.Exists(xmlPath))
                    {
                        option.IncludeXmlComments(xmlPath);
                    }
                }
            })
            .AddSwaggerDocuments(apiName);

            return serviceCollection;
        }

        private static IServiceCollection AddSwaggerDocuments(this IServiceCollection serviceCollection, string swaggerApiName)
        {
            var provider = serviceCollection.BuildServiceProvider().GetRequiredService<IApiVersionDescriptionProvider>();

            foreach (var description in provider.ApiVersionDescriptions)
            {
                serviceCollection.AddSwaggerDocument(config =>
                {
                    config.DocumentName = description.GroupName.ToLower();

                    config.PostProcess = document =>
                    {

                        document.Info.Version = description.GroupName.ToLower();
                        document.Info.Title = swaggerApiName;
                        document.Info.Description = description.IsDeprecated
                            ? "This Api version has been depreciated"
                            : "A versioned TTC Fas Rest API";
                    };

                    config.ApiGroupNames = new[] { description.GroupName.ToLower() };
                });
            }

            return serviceCollection;
        }

所以在我的Progarm.cs中,我会有这样的东西:

\\ Something ...
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerTest("test");

builder.Services.AddAuthentication(authOptions =>
{
    authOptions.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
    authOptions.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
})
.AddJwtBearer(jwtOptions =>
{
    jwtOptions.SaveToken = true;
    jwtOptions.TokenValidationParameters = new TokenValidationParameters
    {
        ValidateAudience = true,
        ValidateIssuer = true,
        ValidateLifetime = true,
        ValidateIssuerSigningKey = true,
        ValidIssuer = "Test",
        ValidAudience = "https://localhost:7117",
        IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("superSecretKey@2410"))
    };
});

var app = builder.Build();

// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
    app.UseOpenApi();
    app.UseSwaggerUi3(config => config.DocExpansion = "list");
}

app.UseHttpsRedirection();

app.UseAuthentication();
app.UseAuthorization();

app.MapControllers();

app.Run();

我的v1控制器:

[ApiController]
    [ApiVersion("1.0")]
    [Route("api/v{version:apiVersion}/[controller]")]
    public class WeatherForecastController : ControllerBase
    {
        private static readonly string[] Summaries = new[]
        {
            "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching", "v1"
        };

        private readonly ILogger<WeatherForecastController> _logger;

        public WeatherForecastController(ILogger<WeatherForecastController> logger)
        {
            _logger = logger;
        }

        [Authorize]
        [HttpGet(Name = "GetWeatherForecast")]
        public IEnumerable<WeatherForecast> Get()
        {
            return Enumerable.Range(1, 5).Select(index => new WeatherForecast
            {
                Date = DateTime.Now.AddDays(index),
                TemperatureC = Random.Shared.Next(-20, 55),
                Summary = Summaries[Random.Shared.Next(Summaries.Length)]
            })
            .ToArray();
        }
    }

v2控制器:

[ApiController]
    [ApiVersion("2.0")]
    [Route("api/v{version:apiVersion}/[controller]")]
    public class WeatherForecastController : ControllerBase
    {
        private static readonly string[] Summaries = new[]
        {
            "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching", "v2"
        };

        private readonly ILogger<WeatherForecastController> _logger;

        public WeatherForecastController(ILogger<WeatherForecastController> logger)
        {
            _logger = logger;
        }

        [Authorize]
        [HttpGet(Name = "GetWeatherForecast")]
        public IEnumerable<WeatherForecast> Get()
        {
            return Enumerable.Range(1, 5).Select(index => new WeatherForecast
            {
                Date = DateTime.Now.AddDays(index),
                TemperatureC = Random.Shared.Next(-20, 55),
                Summary = Summaries[Random.Shared.Next(Summaries.Length)]
            })
            .ToArray();
        }
    }

我还在v1和v2中都有登录控制器。

我已经为自己找到了一个解决方案,我不再使用Nswag.AspnetCore包中的UseOpenApiUseSwaggerUi3了,所以我决定删除这个包,使用Swashbuckle.AspNetCoreSwashbuckle.AspNetCore.SwaggerUI中的UseSwaggerUseSwaggerUI
AddSwaggerTest函数和控制器中的所有内容都是相同的。下面是我如何让它工作的:

\\ something is running
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerTest("test");

builder.Services.AddAuthentication(authOptions =>
{
    authOptions.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
    authOptions.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
})
.AddJwtBearer(jwtOptions =>
{
    jwtOptions.SaveToken = true;
    jwtOptions.TokenValidationParameters = new TokenValidationParameters
    {
        ValidateAudience = true,
        ValidateIssuer = true,
        ValidateLifetime = true,
        ValidateIssuerSigningKey = true,
        ValidIssuer = "Test",
        ValidAudience = "https://localhost:7117",
        IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("superSecretKey@2410"))
    };
});

var app = builder.Build();

var apiVersionDescriptionProvider = app.Services.GetRequiredService<IApiVersionDescriptionProvider>();

// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
    app.UseSwagger();
    app.UseSwaggerUI(c =>
    {
          foreach (var description in apiVersionDescriptionProvider.ApiVersionDescriptions)
          {
                    c.SwaggerEndpoint($"/swagger/{description.GroupName}/swagger.json",
                        description.GroupName.ToUpperInvariant());
          }
    });
}

app.UseHttpsRedirection();

app.UseAuthentication();
app.UseAuthorization();

app.MapControllers();

app.Run();
hc8w905p

hc8w905p1#

由于您使用了AddSecurityDefinitionAddSecurityRequirement,我们应该更改中间件的顺序。

按如下方式更改代码:

var app = builder.Build();

app.UseHttpsRedirection();

app.UseAuthentication();
app.UseAuthorization();

// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
    app.UseOpenApi();
    app.UseSwaggerUi3(config => config.DocExpansion = "list");
}

app.MapControllers();

app.Run();

相关问题