#swagger #identityserver4 #swashbuckle #.net-core-3.1 #clientcredential
#swagger #identityserver4 #swashbuckle #.net-core-3.1 #клиентский кредит
Вопрос:
У меня есть API, который мне нужно авторизовать (используя атрибут [Authorize]). Сервер идентификации 4 настроен с использованием сгенерированной базы данных, включая таблицы Клиенты, Область видимости, ClientScope, Секреты клиента.
У меня есть внутренний клиент с секретным InternalClientSecret, который отлично работает при авторизации из кода.
Но я не могу понять, как настроить right swashbuckle для make swagger делать авторизованные запросы
После нажатия кнопки авторизации:
Также изменяется внешний вид списка API:
Если я обращаюсь к API, я получаю 401, если я нажимаю кнопку блокировки, я вижу:
Код позади:
services.AddSwaggerGen(c =>
{
c.SwaggerDoc("v1.0", new OpenApiInfo { Title = "Main API v1.0", Version = "v1.0" });
if(configuration != null)
{
c.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme
{
Type = SecuritySchemeType.OAuth2,
Flows = new OpenApiOAuthFlows()
{
ClientCredentials = new OpenApiOAuthFlow()
{
TokenUrl = new Uri("https://localhost:44339/connect/token"),
Scopes = new Dictionary<string, string>()
{
{ "LookupsApi", "LookupsApi" }
}
}
},
});
c.AddSecurityRequirement(new OpenApiSecurityRequirement
{
{
new OpenApiSecurityScheme
{
Name = "Bearer",
Scheme = "oauth2",
Type = SecuritySchemeType.OAuth2,
In = ParameterLocation.Header,
Reference = new OpenApiReference
{
Type = ReferenceType.SecurityScheme,
Id = "Bearer"
}
},
new List<string>()
}
});
}
c.OperationFilter<AuthorizeCheckOperationFilter>();
});
return services;
}
public static IApplicationBuilder UseSwaggerDocumentation(this IApplicationBuilder app)
{
app.UseSwagger();
app.UseSwaggerUI(c =>
{
c.SwaggerEndpoint("/swagger/v1.0/swagger.json", "Versioned API v1.0");
c.SwaggerEndpoint("/swagger/v1/swagger.json", "Our Awesome API V1");
c.OAuthClientId("InternalClient");
c.OAuthClientSecret("InternalClientSecret");
});
return app;
}
internal class AuthorizeCheckOperationFilter : Swashbuckle.AspNetCore.SwaggerGen.IOperationFilter
{
public void Apply(OpenApiOperation operation, OperationFilterContext context)
{
var hasAuthorize = context.ApiDescription.CustomAttributes().OfType<AuthorizeAttribute>().Any();
if (hasAuthorize)
{
operation.Responses.Add("401", new OpenApiResponse { Description = "Unauthorized" });
operation.Responses.Add("403", new OpenApiResponse { Description = "Forbidden" });
operation.Security ??= new List<OpenApiSecurityRequirement>(); //new List<IDictionary<string, IEnumerable<string>>>();
var openApiSecurityRequirement = new OpenApiSecurityRequirement();
openApiSecurityRequirement.Add(new OpenApiSecurityScheme { Type = SecuritySchemeType.OAuth2 }, new List<string> {
"LookupsApi"
});
operation.Security.Add(openApiSecurityRequirement);
}
}
}
Что я делаю не так, есть идеи? Или, может быть, у кого-нибудь есть рабочий пример?