在 Asp.Net Core 中使用 Swagger 在请求中未发送授权承载令牌
Posted
技术标签:
【中文标题】在 Asp.Net Core 中使用 Swagger 在请求中未发送授权承载令牌【英文标题】:Authorization Bearer token not being sent in request using Swagger in Asp.Net Core 【发布时间】:2020-09-17 02:05:58 【问题描述】:我正在使用 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
【问题讨论】:
捕获http请求时,是否有Authorization项? @hina10531 不,它不存在 【参考方案1】:罪魁祸首
配置看起来不错。您定义的身份验证名称似乎是罪魁祸首。
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>();
);
除非您手动将securitySchemaName
传递给构造函数,否则您必须将定义名称用作"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);
它在我的环境中运行良好。请尝试使用此配置,请不要忘记添加过滤选项。
【讨论】:
【参考方案2】:您需要在 Swagger UI 中手动添加授权标头。 API 配置需要包含端点的 BearerAuth 架构,如规范 https://swagger.io/docs/specification/authentication/ 中所述。
OpenAPI 使用术语安全方案进行身份验证和 授权方案。 OpenAPI 3.0 让您描述受保护的 API 使用以下安全方案: HTTP 身份验证方案(它们使用 授权标头)、标头中的 API 密钥、查询字符串或 cookie Cookie 身份验证、OAuth 2、OpenID 连接发现
这是通过AddSecurityDefinition
完成的,但您缺少AddSecurityRequirement
,它表示这是端点的要求,并且它在UI 中呈现,正如answer 中所述。 here 也是一个自动添加标题的选项。
【讨论】:
我已添加此代码,但仍未发送自动化标头 options.AddSecurityRequirement(new OpenApiSecurityRequirement() new OpenApiSecurityScheme Reference = new OpenApiReference Type = ReferenceType.SecurityScheme, Id = "Bearer" , Scheme = "oauth2", Name = "Bearer", In = ParameterLocation.Header, , new List以上是关于在 Asp.Net Core 中使用 Swagger 在请求中未发送授权承载令牌的主要内容,如果未能解决你的问题,请参考以下文章
在 ASP.NET Core 6.0 中使用 Serilog
如何在 ASP.Net Core 中使用 IHostedService
ASP.NET Core Web 应用程序系列- 在ASP.NET Core中使用Autofac替换自带DI进行批量依赖注入(MVC当中应用)