Swagger UI: передать пользовательский заголовок авторизации

Я использую Swashbuckle и Swagger на ASP.NET Web API. Я пытаюсь найти способ передать заголовок авторизации, содержащий токен носителя, через Swagger UI. Я искал вокруг, но все ответы, кажется, указывают на этой ссылка.

однако это предполагает, что содержимое заголовка известно заранее. Мне действительно нужен способ изменить заголовок в Swagger UI (прямо перед ударом " попробуйте!'button), потому что токен на предъявителя истекает каждый час. Что-то похожее на то, как Postman позволяет добавлять заголовки.

Это кажется до смешного простой вопрос, но каков ответ?

3 ответов


мы столкнулись с той же проблемой на наш проект. Я также хотел добавить параметры заголовка на веб-сайт Swagger UI. Вот как мы это сделали:--3-->

1. Определите класс OperationFilter OperationFilters выполняются на каждой операции API каждый раз, когда вы строите Swagger. Согласно вашему коду, операции будут проверяться в соответствии с вашими фильтрами. В этом примере мы делаем параметр header обязательным для каждой операции, но делаем его необязательным для операций, которые имеют атрибут атрибута allowanonymous.

public class AddAuthorizationHeader : IOperationFilter
{
    /// <summary>
    /// Adds an authorization header to the given operation in Swagger.
    /// </summary>
    /// <param name="operation">The Swashbuckle operation.</param>
    /// <param name="schemaRegistry">The Swashbuckle schema registry.</param>
    /// <param name="apiDescription">The Swashbuckle api description.</param>
    public void Apply(Operation operation, SchemaRegistry schemaRegistry, ApiDescription apiDescription)
    {
        if (operation == null) return;

        if (operation.parameters == null)
        {
            operation.parameters = new List<Parameter>();
        }

        var parameter = new Parameter
        {
            description = "The authorization token",
            @in = "header",
            name = "Authorization",
            required = true,
            type = "string"
        };

        if (apiDescription.ActionDescriptor.GetCustomAttributes<AllowAnonymousAttribute>().Any())
        {
            parameter.required = false;
        }

        operation.parameters.Add(parameter);
    }
}

2. Скажите Swagger использовать этот OperationFilter В SwaggerConfig просто добавьте, что фильтр операции должен использоваться следующим образом:

c.OperationFilter<AddAuthorizationHeader>();

надеюсь, это поможет вам!


создайте новый фильтр операций, который реализует IOperationFilter.

public class AuthorizationHeaderOperationFilter : IOperationFilter
{
    /// <summary>
    /// Adds an authorization header to the given operation in Swagger.
    /// </summary>
    /// <param name="operation">The Swashbuckle operation.</param>
    /// <param name="context">The Swashbuckle operation filter context.</param>
    public void Apply(Operation operation, OperationFilterContext context)
    {
        if (operation.Parameters == null)
        {
            operation.Parameters = new List<IParameter>();
        }

        var authorizeAttributes = context.ApiDescription
            .ControllerAttributes()
            .Union(context.ApiDescription.ActionAttributes())
            .OfType<AuthorizeAttribute>();
        var allowAnonymousAttributes = context.ApiDescription.ActionAttributes().OfType<AllowAnonymousAttribute>();

        if (!authorizeAttributes.Any() && !allowAnonymousAttributes.Any())
        {
            return;
        }

        var parameter = new NonBodyParameter
        {
            Name = "Authorization",
            In = "header",
            Description = "The bearer token",
            Required = true,
            Type = "string"
        };

        operation.Parameters.Add(parameter);
    }
}

настройте службу в своем .

        services.ConfigureSwaggerGen(options =>
        {
            options.OperationFilter<AuthorizationHeaderOperationFilter>();
        });

вы могли бы сделать это по-разному в зависимости от того, как вы собираете Authorization заголовок и хотите ли вы, чтобы код, чтобы обрабатывать все, или если вы хотите, чтобы пользователь мог ввести что-нибудь Authorization заголовок, который они хотят.

когда я впервые попробовал это, я смог показать Authorization текст заголовка в области полей параметров каждой конечной точки, где пользователь может ввести Authorization заголовок, но это было не то, что я хотел.

в моей ситуации, я должен был отправить запрос в /token конечная точка с cookie пользователя, чтобы получить действительный Authorization маркер. Поэтому я сделал несколько вещей, чтобы достичь этого.

сначала в SwaggerConfig.cs я раскомментируйте строчку c.BasicAuth() чтобы получить основную схему аутентификации в схему API, и я также ввел пользовательский index.html страница, где я вставил запрос AJAX, чтобы захватить Authorization маркер, используя cookie пользователя (index.html код, показанный ниже):

public static void Register() {

    System.Reflection.Assembly thisAssembly = typeof(SwaggerConfig).Assembly;

    System.Web.Http.GlobalConfiguration.Configuration
                .EnableSwagger(c => {
                    ...

                    c.BasicAuth("basic").Description("Bearer Token Authentication");

                    ...
                })
                .EnableSwaggerUi(c => {
                    ...

                    c.CustomAsset("index", thisAssembly, "YourNamespace.index.html");

                    ...
                });
}

затем глава здесь чтобы загрузить swashbuckle index.html который мы настроим, чтобы вставить Authorization заголовок.

ниже я просто делаю вызов AJAX для моего /token конечная точка с допустимым cookie, получите Authorization токен и дайте его swagger для использования с window.swaggerUi.api.clientAuthorizations.add():

...

function log() {
  if ('console' in window) {
    console.log.apply(console, arguments);
  }
}

$.ajax({
    url: url + 'token'
  , type: 'POST'
  , data: { 'grant_type': 'CustomCookie' }
  , contentType: 'application/x-www-form-urlencoded'
  , async: true
  , timeout: 60000
  , cache: false
  , success: function(response) {
        console.log('Token: ' + response['token_type'] + ' ' + response['access_token']);
        window.swaggerUi.api.clientAuthorizations.add("key", new SwaggerClient.ApiKeyAuthorization("Authorization", response['token_type'] + ' ' + response['access_token'], "header"));
    }
  , error: function(request, status, error) {
        console.log('Status: ' + status + '. Error: ' + error + '.');
    }
});

я удалил кое-что из AJAX-вызов, чтобы сделать его более простым и, очевидно, ваша реализация может отличаться в зависимости от того, как вы собираете свой Authorization токен и прочее, но это дает вам идею. Если у вас есть какие-либо конкретные вопросы или проблемы, дайте мне знать.

*Edit: не заметил, что вы на самом деле хотели, чтобы пользователь ввел их Authorization заголовок. В таком случае это очень просто. Я использовал этой пост. Просто создал следующий класс для выполнения работы:

public class AddRequiredHeaderParameter : IOperationFilter {

    public void Apply(Operation operation, SchemaRegistry schemaRegistry, ApiDescription apiDescription) {
        if (operation.parameters == null) {
            operation.parameters = new List<Parameter>();
        }

        operation.parameters.Add(new Parameter {
            name = "Foo-Header",
            @in = "header",
            type = "string",
            required = true
        });
    }
}

затем добавил класс в my SwaggerConfig вот так:

...
c.OperationFilter<AddRequiredHeaderParameter>();
...