无法在asp.net core中为swagger api文档添加授权

问题描述 投票:0回答:1

我有一个用于多个 api 版本控制的 asp.net core 6 项目设置。但是,当我打开 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 中都有登录控制器。

================================================= ==========

我自己找到了解决办法。我没有使用

UseOpenApi
UseSwaggerUi3
不再来自
Nswag.AspnetCore
包,所以我决定删除这个包并使用
UseSwagger
UseSwaggerUI
来自
Swashbuckle.AspNetCore
Swashbuckle.AspNetCore.SwaggerUI

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();

asp.net-core swagger swagger-ui nswag
1个回答
0
投票

既然你使用了

AddSecurityDefinition
AddSecurityRequirement
,我们应该改变中间件的顺序。

像下面这样更改您的代码:

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();
© www.soinside.com 2019 - 2024. All rights reserved.