Swagger 是否可以从 URL 查询字符串中获取授权令牌?

Ang*_*ker 2 c# swagger .net-core swashbuckle

在 .NET Core 项目中,我添加了一个安全定义(底部的代码),它向页面添加了一个授权按钮,用户可以输入 api 密钥 - 一切正常。

是否可以在 URL 中指定 api 密钥,以便 Swagger 自动使用该密钥,而不必输入它?类似/swagger/index.html?authorization=0123456789或类似的东西。

现有代码:

services.AddSwaggerGen(c => {
  ...
  c.AddSecurityDefinition("api key", new ApiKeyScheme() {
      Description = "Authorization query string expects API key",
      In = "query",
      Name = "authorization",
      Type = "apiKey"
  });

  var requirements = new Dictionary<string, IEnumerable<string>> {
      { "api key", new List<string>().AsEnumerable() }
  };
  c.AddSecurityRequirement(requirements);
});
Run Code Online (Sandbox Code Playgroud)

看起来带有authorization参数的 URL 应该可以工作,但事实并非如此。

PS 使用 Swashbuckle 4.0.x

tim*_*mur 7

这确实是可能的,但您必须覆盖 Swagger-UI 的索引页面,以便可以将自定义处理程序插入onComplete回调中。

  1. 从Swashbuckle 的源代码库中获取最新的 index.html (理想情况下,获取匹配的版本)
  2. 调整configObject以添加回调处理程序,以便在 UI 准备就绪时OnComplete调用preauthorizeApiKey
  3. 重写IndexStream扩展UserSwaggerUI方法以提供自定义 html

我最终得到了以下设置(为简洁起见,省略了一些位):

wwwroot/swashbuckle.html

<!-- your standard HTML here, nothing special -->
<script>
    // some boilerplate initialisation
    // Begin Swagger UI call region
    configObject.onComplete = () => {

        // get the authorization portion of the query string
        var urlParams = new URLSearchParams(window.location.search);
        if (urlParams.has('authorization')) {
            var apikey = urlParams.get('authorization');

            // this is the important bit, see documentation
            ui.preauthorizeApiKey('api key', apikey );// key name must match the one you defined in AddSecurityDefinition method in Startup.cs
       }
    }
    const ui = SwaggerUIBundle(configObject);
    window.ui = ui        
}
</script>
Run Code Online (Sandbox Code Playgroud)

启动.cs

    public void ConfigureServices(IServiceCollection services)
    {
        .........
        services.AddSwaggerGen(c => {
            c.SwaggerDoc("v1", new Info { Title = "You api title", Version = "v1" });
            c.AddSecurityDefinition("api key", new ApiKeyScheme() // key name must match the one you supply to preauthorizeApiKey call in JS
            {
                Description = "Authorization query string expects API key",
                In = "query",
                Name = "authorization",
                Type = "apiKey"
            });

            var requirements = new Dictionary<string, IEnumerable<string>> {
                { "api key", new List<string>().AsEnumerable() }
            };
            c.AddSecurityRequirement(requirements);
        });
    }

    // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
    public void Configure(IApplicationBuilder app, IHostingEnvironment env)
    {
        app.UseSwagger();
        app.UseSwaggerUI(c =>
        {
            c.IndexStream = () => File.OpenRead("wwwroot/swashbuckle.html"); // this is the important bit. see documentation https://github.com/domaindrivendev/Swashbuckle.AspNetCore/blob/master/README.md
            c.SwaggerEndpoint("/swagger/v1/swagger.json", "My API V1"); // very standard Swashbuckle init
        });
        app.UseMvc();
    }
Run Code Online (Sandbox Code Playgroud)

完成所有这些操作后,使用 ?authorization=1234567890 调用标准 swagger URL 应该会自动授权该页面。