使用 .NET Core 3.0 的 JWT 身份验证和 Swagger

JWT Authentication and Swagger with .NET Core 3.0

我正在使用 .NET Core 3.0 开发一些 Web API,并希望将其与 SwashBuckle.Swagger 集成。 它工作正常,但是当我添加 JWT 身份验证时,它并没有像我预期的那样工作。 为此,我添加了以下代码:

services.AddSwaggerGen(c =>
    {
        c.SwaggerDoc("v1", new Microsoft.OpenApi.Models.OpenApiInfo { Title = "My Web API", Version = "v1" });
        c.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme
        {
            Description = "JWT Authorization header using the Bearer scheme. Example: \"Authorization: Bearer {token}\"",
            Name = "Authorization",
            In = ParameterLocation.Header,
            Type = SecuritySchemeType.ApiKey
        });
    });

添加AddSecurityDefinition功能后,我可以看到授权按钮,当我点击它时,我看到下面的表格:

然后我输入 Bearer WhatEverApiKeyIsfgdgdgdg845734987fgdhgiher635kjh。完成后,当我从 Swagger 向 Web API 发送请求时,我希望在请求的 header 中看到 authorization: Bearer WhatEverApiKeyIsfgdgdgdg845734987fgdhgiher635kjh,但未向请求添加授权 header .我正在使用 SwashBuckle.Swagger(5.0.0-rc3)。请注意,有许多示例在 .NET Core 2.0 上运行良好,但 Swashbuckle swagger 函数在最新版本中发生了变化,因此我无法使用这些示例。

经过一番研究,我终于找到了答案here

在看到这个页面之前,我知道我应该在 AddSecurityDefinition 之后使用 AddSecurityRequirement 因为示例很多,但问题是函数参数在 .NET Core 3.0 上发生了变化。

对了,最终答案如下:

services.AddSwaggerGen(c =>
{
  c.SwaggerDoc("v1", new OpenApiInfo { 
    Title = "My API", 
    Version = "v1" 
  });
  c.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme {
    In = ParameterLocation.Header, 
    Description = "Please insert JWT with Bearer into field",
    Name = "Authorization",
    Type = SecuritySchemeType.ApiKey 
  });
  c.AddSecurityRequirement(new OpenApiSecurityRequirement {
   { 
     new OpenApiSecurityScheme 
     { 
       Reference = new OpenApiReference 
       { 
         Type = ReferenceType.SecurityScheme,
         Id = "Bearer" 
       } 
      },
      new string[] { } 
    } 
  });
});

如果您不想手动添加令牌,并且希望在将 clientId 传递给身份服务器的同时选择范围,则可以添加类似这样的内容。

我使用了隐式流,但您可以使用以下机制配置任何流:

options.AddSecurityDefinition("oauth2", new OpenApiSecurityScheme()
{
  Flows = new OpenApiOAuthFlows
  {
    Implicit = new OpenApiOAuthFlow
    {                            
      AuthorizationUrl = new Uri("http://localhost"),
      TokenUrl = new Uri("http://localhost"),
      Scopes = new Dictionary<string, string>
      {
        { "Foundation API", "FoundationApi" }
      }
    }
  },
  In = ParameterLocation.Header,                    
  Name = "Authorization",
  Type = SecuritySchemeType.OAuth2                    
});

输出将是这样的:

如果您使用的是 Swagger 3.0,那么它 build-in 支持 JWT 身份验证。

您需要在 OpenApiSecurityScheme 中使用 ParameterLocation.Header、SecuritySchemeType.Http、bearer 和 JWT,如下所示。

在此之后,您不需要以 Bearer {token} 格式指定令牌。仅指定令牌,安全方案将自动将其应用到 header.

// Bearer token authentication
OpenApiSecurityScheme securityDefinition = new OpenApiSecurityScheme()
{
    Name = "Bearer",
    BearerFormat = "JWT",
    Scheme = "bearer",
    Description = "Specify the authorization token.",
    In = ParameterLocation.Header,
    Type = SecuritySchemeType.Http,
};
c.AddSecurityDefinition("jwt_auth", securityDefinition);

// Make sure swagger UI requires a Bearer token specified
OpenApiSecurityScheme securityScheme = new OpenApiSecurityScheme()
{
    Reference = new OpenApiReference()
    {
        Id = "jwt_auth",
        Type = ReferenceType.SecurityScheme
    }
};
OpenApiSecurityRequirement securityRequirements = new OpenApiSecurityRequirement()
{
    {securityScheme, new string[] { }},
};
c.AddSecurityRequirement(securityRequirements);

如果有人正在使用 NSwag 并在搜索解决方案后登陆这里,这里是来自官方文档的link。

NSwag Enable JWT authentication

PS:我知道最初的问题是针对 SwashBuckle 的,但是 Google 在搜索 NSwag 时也首先显示了这个 link。

这是为 Swashbuckle.AspNetCore 5.3.2 更新的解决方案,与 IdentityServer4 集成,API 使用 Bearer 令牌保护。

ConfigureServices()方法中:

services.AddSwaggerGen(options =>
{
    options.SwaggerDoc("v1", new OpenApiInfo { Title = "My API", Version = "v1" });
    options.AddSecurityDefinition("Bearer", SecuritySchemes.BearerScheme(Configuration));
    options.AddSecurityRequirement(new OpenApiSecurityRequirement()
    {
        { SecuritySchemes.OAuthScheme, new List<string>() }
    });
});

Configure()方法中:

        app.UseSwaggerUI(options =>
        {
            options.SwaggerEndpoint("/My.Api/swagger/v1/swagger.json", "My API V1");
            options.OAuthClientId(Clients.TestClient);
            options.OAuthAppName("My Api - Swagger");
            options.OAuthClientSecret(Configuration["TestClientSecret"]);
        });

internal static class SecuritySchemes
{
    public static OpenApiSecurityScheme BearerScheme(IConfiguration config) => new OpenApiSecurityScheme
    {
        Type = SecuritySchemeType.OAuth2,
        Description = "Standard authorisation using the Bearer scheme. Example: \"bearer {token}\"",
        In = ParameterLocation.Header,
        Name = "Authorization",
        Scheme = "Bearer",
        OpenIdConnectUrl = new System.Uri($"{config["TokenServerUrl"]}.well-known/openid-configuration"),
        BearerFormat = "JWT",
        Flows = new OpenApiOAuthFlows
        {
            Password = new OpenApiOAuthFlow
            {
                AuthorizationUrl = new System.Uri($"{config["TokenServerUrl"]}connect/authorize"),
                Scopes = new Dictionary<string, string>
                    {
                        { Scopes.Api, "My Api" }
                    },
                TokenUrl = new System.Uri($"{config["TokenServerUrl"]}connect/token")
            }
        }
    };

    public static OpenApiSecurityScheme OAuthScheme => new OpenApiSecurityScheme
    {
        Reference = new OpenApiReference
        {
            Type = ReferenceType.SecurityScheme,
            Id = "Bearer"
        },
        Scheme = "oauth2",
        Name = "Bearer",
        In = ParameterLocation.Header,

    };
}

在接受的答案中,“Bearer”需要写在实际令牌之前。 可以跳过键入 “Bearer”的类似方法 如下:

c.SwaggerDoc("v1", new OpenApiInfo { Title = "Example API", Version = "v1" });

c.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme
{
    Type = SecuritySchemeType.Http,
    BearerFormat = "JWT",
    In = ParameterLocation.Header,
    Scheme = "bearer",
    Description = "Please insert JWT token into field"
});

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

此处,只需粘贴 JWT 令牌即可。

在 Accept answer 中,您必须手动将“bearer”附加到 token,这会产生新问题,Swagger 可以附加“bearer”和 token 看下面 link

JWT Authentication and Swagger with .NET Core 3 and 5 YouTube video