SwaggerUI с авторизацией токена-носителя .NetCore 3.0
Я пытаюсь добавить заголовок авторизации в тест 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();
});
}
Кнопка авторизации была добавлена в пользовательский интерфейс Swagger, и я ввел требуемый токен доступа, как показано ниже.
но проблема в том, что когда я хочу попробовать API, токен не добавляется в запрос API, и когда я нажимаю значок замка над API, он показывает, что нет доступной авторизации, см. ниже
4 ответа
Моя реализация - исключает блокировки на незащищенных конечных точках - с 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.DeclaringType.GetCustomAttributes(true).OfType<AllowAnonymousAttribute>().Any()) //this excludes controllers with AllowAnonymous attribute in case base controller has Authorize attribute
|| (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
декорированные методы
В вашем коде есть два пункта:
- За
OpenApiSecurityRequirement
вOpenApiSecurityRequirement
, необходимо установитьOpenApiReference
- Необходимо указать
Scheme
с участиемbearer
Вот рабочая демонстрация:
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.Http,
Scheme = "bearer",
Reference = new OpenApiReference
{
Type = ReferenceType.SecurityScheme,
Id = "Bearer"
}
};
c.AddSecurityDefinition("Bearer", securitySchema);
var securityRequirement = new OpenApiSecurityRequirement();
securityRequirement.Add(securitySchema, new[] { "Bearer" });
c.AddSecurityRequirement(securityRequirement);
});
Обратите внимание, что после.Net Core 3.0 тип некоторых параметров был изменен следующим образом:
In = ParameterLocation.Header,
Тип = 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/
В дополнение к тому, что сказал Кирил, в моем случае я хочу получить токен JWT через Swagger, и это код, который я использовал, добавив OpenApiSecurityScheme к тому, что он предложил:
c.AddSecurityDefinition("bearer",
new OpenApiSecurityScheme{
Flows = new OpenApiOAuthFlows()
{
ClientCredentials = new OpenApiOAuthFlow()
{
TokenUrl = new Uri("https://auth.myauthserver.com/oauth2/token"),
Scopes = new Dictionary<string, string>(){ {"myscope", "Access API"}},
AuthorizationUrl = new Uri("https://auth.myauthserver.com/oauth2/authorize")
}
},
Type = SecuritySchemeType.OAuth2,
OpenIdConnectUrl = new Uri("https://myauthserver/.well-known/openid-configuration"),
BearerFormat = "JWT",
In = ParameterLocation.Header,
Scheme = "bearer"
});