【问题标题】:Transitioning to Swashbuckle 5.0过渡到 Swashbuckle 5.0
【发布时间】:2019-11-05 16:43:23
【问题描述】:

我通过 Swashbuckle V4 使用 Swagger,通过 API KEY 对端点进行身份验证。

以下配置在使用 Swashbuckle V4 时完美运行(请注意,仅显示 Swagger 代码):

public void ConfigureServices(IServiceCollection services) {

 services.AddSwaggerGen(c => {
  c.SwaggerDoc(
   "v1",
   new Info {
    Title = "OAPI", Version = "v1"
   });
  c.AddSecurityDefinition("api_key", new ApiKeyScheme {
    In = "query",
    Description = "Please Enter Authentication Token",
    Name = "key",
    Type = "apiKey"
  });
  c.AddSecurityRequirement(new Dictionary < string, IEnumerable < string >> {
   {
    "api_key",
    new [] {
     "readAccess",
     "writeAccess"
    }
   }
  });
 });
}

public void Configure(IApplicationBuilder app, IHostingEnvironment env) {

 app.UseSwagger();

 app.UseSwaggerUI(c => {
  c.SwaggerEndpoint("/api/swagger/v1/swagger.json", "API V1");
  c.RoutePrefix = "api/swagger";
 });
}

Swashbuckle GitHub page,包含一个“Transitioning to Swashbuckle 5.0”主题,但不包括 API 密钥的使用。

我无法找到有关如何过渡到 V5 的完整示例,因此我分析了方法签名以生成相同的配置。

以下代码假装复制上述 V4 配置:

public void ConfigureServices(IServiceCollection services) {

 var securityScheme = new OpenApiSecurityScheme {
   In = ParameterLocation.Query,
   Description = "Please Enter Authentication Token",
   Name = "key",
   Type = SecuritySchemeType.ApiKey
 };

 services.AddSwaggerGen(c => {
  c.SwaggerDoc("V1", new OpenApiInfo {
    Version = "V1",
    Title = "API",
    Description = "API"
  });

  c.AddSecurityDefinition("api_key", securityScheme);

  c.AddSecurityRequirement(new OpenApiSecurityRequirement {
   {
    securityScheme,
    new [] {
     "readAccess",
     "writeAccess"
    }
   }
  });

  c.EnableAnnotations();
 });
}

public void Configure(IApplicationBuilder app, IHostingEnvironment env) {

 app.UseSwagger();

 app.UseSwaggerUI(c => {
  c.SwaggerEndpoint("/api/swagger/v1/swagger.json", "API V1");
  c.RoutePrefix = "api/swagger";
 });
}

运行 API 时,会显示 Swagger 身份验证窗口,我可以使用 API KEY 进行身份验证。

不幸的是,在执行任何 Endpoint 时,我收到以下错误:

 System.InvalidOperationException: No authenticationScheme was specified, and there was no DefaultChallengeScheme found.

        at Microsoft.AspNetCore.Authentication.AuthenticationService.ChallengeAsync
        at Microsoft.AspNetCore.Mvc.ChallengeResult.ExecuteResultAsync
        at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.InvokeResultAsync
        at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.InvokeNextResultFilterAsync[TFilter,TFilterAsync]
        at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.Rethrow
        at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.ResultNext[TFilter,TFilterAsync]
        at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.InvokeAlwaysRunResultFilters
        at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.InvokeFilterPipelineAsync
        at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.InvokeAsync
        at Microsoft.AspNetCore.Routing.EndpointMiddleware.Invoke
        at Microsoft.AspNetCore.Routing.EndpointRoutingMiddleware.Invoke
        at Microsoft.AspNetCore.StaticFiles.StaticFileMiddleware.Invoke
        at Swashbuckle.AspNetCore.SwaggerUI.SwaggerUIMiddleware.Invoke
        at Swashbuckle.AspNetCore.Swagger.SwaggerMiddleware.Invoke
        at Microsoft.AspNetCore.Cors.Infrastructure.CorsMiddleware.InvokeCore

我认为我缺少一些东西,我试图研究 Microsoft.OpenApi.Models 类,但到目前为止我没有运气。大概是个小细节,但至今没能看懂……

【问题讨论】:

    标签: swagger swashbuckle


    【解决方案1】:

    您需要在使用AddSecurityRequirement 时引用该方案,因为您是在全局应用它。 此外,当使用“oauth2”以外的任何其他类型时,范围数组必须为空。

    下面的例子应该可以工作。

    c.AddSecurityRequirement(new OpenApiSecurityRequirement
                    {
                        {
                            new OpenApiSecurityScheme
                            {
                                Reference = new OpenApiReference
                                {
                                    Id = "api_key",
                                    Type = ReferenceType.SecurityScheme
                                }
                            },
                            new List<string>() }
                    });
    

    【讨论】:

      【解决方案2】:

      除了做@Pavlos 说的,你还需要使用 AddAuthentication(string defaultScheme) 来指定默认的 authenticationScheme。 例如:

      services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
      

      或者在RequireAuthorization方法中指定authorizeData。

      app.UseEndpoints(endpoints =>
      {
          endpoints.MapControllers()
              .RequireAuthorization(new AuthorizeAttribute() { AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme });
      });
      

      你可以使用多个 AuthenticationSchemes,用逗号加入它们。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-05-07
        • 1970-01-01
        • 1970-01-01
        • 2014-03-15
        • 2015-06-22
        相关资源
        最近更新 更多