我正在使用Swagger在Asp.Net Core应用程序中测试我的API。我通过输入像Authorization: Bearer {token}
这样的令牌来发送请求。但未在请求中发送授权标头。
Asp.Net Core 3.1版和Swashbuckle.AspNetCore 5.4.1
Startup.cs代码:
public class Startup
{
private const string _apiVersion = "v1";
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(options =>
{
options.TokenValidationParameters = new TokenValidationParameters
{
ClockSkew = TimeSpan.FromMinutes(0),
ValidateIssuer = true,
ValidateAudience = true,
ValidateLifetime = true,
ValidateIssuerSigningKey = true,
ValidIssuer = Configuration["Jwt:Issuer"],
ValidAudience = Configuration["Jwt:Issuer"],
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Configuration["Jwt:Key"]))
};
});
services.AddSwaggerGen(options =>
{
options.SwaggerDoc("v1", new OpenApiInfo
{
Version = "v1",
Title = "MyProject API",
Description = "MyProject"
});
options.DocInclusionPredicate((docName, description) => true);
// Define the BearerAuth scheme that's in use
options.AddSecurityDefinition("bearerAuth", new OpenApiSecurityScheme()
{
Description = "JWT Authorization header using the Bearer scheme. Example: \"Authorization: Bearer {token}\"",
Name = "Authorization",
In = ParameterLocation.Header,
Type = SecuritySchemeType.ApiKey
});
});
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env, ILoggerFactory loggerFactory)
{
app.UseAuthentication();
loggerFactory.AddLog4Net();
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseRouting();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
// Enable middleware to serve generated Swagger as a JSON endpoint
app.UseSwagger(c => { c.RouteTemplate = "swagger/{documentName}/swagger.json"; });
// Enable middleware to serve swagger-ui assets (HTML, JS, CSS etc.)
app.UseSwaggerUI(options =>
{
// specifying the Swagger JSON endpoint.
options.SwaggerEndpoint($"/swagger/{_apiVersion}/swagger.json", $"MyProject API {_apiVersion}");
//options.IndexStream = () => Assembly.GetExecutingAssembly()
// .GetManifestResourceStream("MyProject.Web.Host.wwwroot.swagger.ui.index.html");
options.DisplayRequestDuration(); // Controls the display of the request duration (in milliseconds) for "Try it out" requests.
}); // URL: /swagger
}
}
配置看起来不错。似乎您定义的身份验证名称可能是罪魁祸首。
services.AddSwaggerGen(options =>
{
options.SwaggerDoc("v1", new OpenApiInfo
{
Version = "v1",
Title = "MyProject API",
Description = "MyProject"
});
options.DocInclusionPredicate((docName, description) => true);
// options.AddSecurityDefinition("bearerAuth", new OpenApiSecurityScheme()
// "bearerAuth" -> "oauth2"
options.AddSecurityDefinition("oauth2", new OpenApiSecurityScheme()
{
Description = "JWT Authorization header using the Bearer scheme. Example: \"Authorization: Bearer {token}\"",
Name = "Authorization",
In = ParameterLocation.Header,
Type = SecuritySchemeType.ApiKey
});
// Add this filter as well.
options.OperationFilter<SecurityRequirementsOperationFilter>();
});
您必须将定义名称用作"oauth2"
,因为SecurityRequirementsOperationFilter
默认在其构造函数中使用该名称。只需查看securitySchemaName
的默认值即可。
public SecurityRequirementsOperationFilter(bool includeUnauthorizedAndForbiddenResponses = true, string securitySchemaName = "oauth2")
{
Func<IEnumerable<AuthorizeAttribute>, IEnumerable<string>> policySelector = (IEnumerable<AuthorizeAttribute> authAttributes) => authAttributes.Where((Func<AuthorizeAttribute, bool>)((AuthorizeAttribute a) => !string.IsNullOrEmpty(a.Policy))).Select((Func<AuthorizeAttribute, string>)((AuthorizeAttribute a) => a.Policy));
filter = new SecurityRequirementsOperationFilter<AuthorizeAttribute>(policySelector, includeUnauthorizedAndForbiddenResponses, securitySchemaName);
}
在我的环境中效果很好。请尝试使用此配置,并且请不要忘记添加过滤器选项。
您需要在Swagger UI中手动添加Authorization标头。 API配置需要包含端点的BearerAuth架构,如规范https://swagger.io/docs/specification/authentication/中所述。
OpenAPI使用术语安全方案进行身份验证和授权方案。 OpenAPI 3.0可让您描述受保护的API使用以下安全方案:HTTP身份验证方案(它们使用授权标头),标头中的API密钥,查询字符串或cookie Cookie身份验证,OAuth 2,OpenID Connect发现]
这是通过AddSecurityDefinition
完成的,但是您缺少AddSecurityRequirement
,它说这是端点的要求,并且按answer中的描述在UI中呈现。另外here是自动添加标题的选项。