使用 .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
我正在使用 .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