SwaggerUI APIテストに認証ヘッダーを追加しようとしています。以下は私のStartup.csです
public void ConfigureServices(IServiceCollection services)
{
services.AddControllers();
services.Configure<ApiBehaviorOptions>(options =>
{
options.SuppressModelStateInvalidFilter = true;
});
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_3_0);
services.AddSwaggerGen(c =>
{
c.SwaggerDoc("v1", new OpenApiInfo
{
Version = "v1",
Title = "API",
Description = "QPIN API with ASP.NET Core 3.0",
Contact = new OpenApiContact()
{
Name = "Tafsir Dadeh Zarrin",
Url = new Uri("http://www.tdz.co.ir")
}
});
var securitySchema = new OpenApiSecurityScheme
{
Description = "JWT Authorization header using the Bearer scheme. Example: \"Authorization: Bearer {token}\"",
Name = "Authorization",
In = ParameterLocation.Header,
Type = SecuritySchemeType.ApiKey
};
c.AddSecurityDefinition("Bearer", securitySchema);
var securityRequirement = new OpenApiSecurityRequirement();
securityRequirement.Add(securitySchema, new[] { "Bearer" });
c.AddSecurityRequirement(securityRequirement);
});
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env, IServiceProvider serviceProvider)
{
app.UseCors("Cors");
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseMiddleware<ApiResponseMiddleware>();
app.UseSwagger();
app.UseSwaggerUI(c =>
{
c.SwaggerEndpoint("/swagger/v1/swagger.json", "My API V1");
});
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
}
AuthorizeボタンがSwagger UIに追加され、以下に示すように必要なアクセストークンを入力しました
しかし問題は、APIを試したいときにトークンがAPIリクエストに追加されず、APIの上にあるロックアイコンをクリックしたときに、使用可能な認証がないことを示しています。以下を参照してください。
私の実装-保護されていないエンドポイントのロックを除外-OperationFilter
internal static void SwaggerSetup(this IServiceCollection services, OpenApiInfo settings)
{
if (settings.Version != null)
{
services.AddSwaggerGen(c =>
{
c.SwaggerDoc(settings.Version, settings);
c.OperationFilter<AddAuthHeaderOperationFilter>();
c.AddSecurityDefinition("bearer", new OpenApiSecurityScheme
{
Description = "`Token only!!!` - without `Bearer_` prefix",
Type = SecuritySchemeType.Http,
BearerFormat = "JWT",
In = ParameterLocation.Header,
Scheme = "bearer"
});
});
}
}
とOperationFilter
private class AddAuthHeaderOperationFilter : IOperationFilter
{
public void Apply(OpenApiOperation operation, OperationFilterContext context)
{
var isAuthorized = (context.MethodInfo.DeclaringType.GetCustomAttributes(true).OfType<AuthorizeAttribute>().Any()
|| context.MethodInfo.GetCustomAttributes(true).OfType<AuthorizeAttribute>().Any())
&& !context.MethodInfo.GetCustomAttributes(true).OfType<AllowAnonymousAttribute>().Any(); // this excludes methods with AllowAnonymous attribute
if (!isAuthorized) return;
operation.Responses.TryAdd("401", new OpenApiResponse { Description = "Unauthorized" });
operation.Responses.TryAdd("403", new OpenApiResponse { Description = "Forbidden" });
var jwtbearerScheme = new OpenApiSecurityScheme
{
Reference = new OpenApiReference { Type = ReferenceType.SecurityScheme, Id = "bearer" }
};
operation.Security = new List<OpenApiSecurityRequirement>
{
new OpenApiSecurityRequirement { [jwtbearerScheme] = new string []{} }
};
}
}
リファレンス https://thecodebuzz.com/jwt-authorize-swagger-using-ioperationfilter-asp-net-core/
AllowAnonymous
装飾されたメソッドを除外するための条件を追加しました
一部のパラメーターのタイプは、.Net Core 3.0以降、次のように変更されています。
In= ParameterLocation.Header、
Type= SecuritySchemeType.ApiKey
services.AddSwaggerGen(c =>
{
c.SwaggerDoc("v1", new OpenApiInfo { Title = "My 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
});
});
リファレンス: https://ppolyzos.com/2017/10/30/add-jwt-bearer-authorization-to-swagger-and-asp-net-core/