web-dev-qa-db-ja.com

Swagger UI:カスタム認証ヘッダーを渡す

ASP.NET Web APIでSwashbuckleとSwaggerを使用しています。 Swagger UIを介して、ベアラートークンを含むAuthorizationヘッダーを渡す方法を見つけようとしています。私は周りを検索してきましたが、すべての答えは this リンクを指しているようです。

ただし、これはヘッダーの内容が事前にわかっていることを前提としています。 Bearerトークンは1時間ごとに期限切れになるため、Swagger UI内でヘッダーを変更する方法が本当に必要です([試してみる]ボタンを押す直前)。 Postmanでヘッダーを追加できる方法に似たもの。

とんでもないほど単純な問題のようですが、答えは何ですか?

10
fikkatra

私たちのプロジェクトでも同じ問題が発生しました。また、Swagger UI Webサイトにヘッダーパラメーターを追加したいと思っていました。これが私たちのやり方です:

1。OperationFilterクラスを定義する Swaggerをビルドするたびに、すべてのAPI操作でOperationFiltersが実行されます。あなたのコードによれば、操作はあなたのフィルターに従ってチェックされます。この例では、すべての操作で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>();

これがあなたを助けることを願っています!

22

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);
    }
}

Startup.csファイルでサービスを構成します。

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

Authorizationヘッダーの収集方法と、コードですべてを処理するか、ユーザーが必要なAuthorizationヘッダーをユーザーが入力できるようにするかによって、さまざまな方法でそれを行うことができます。

私が最初にこれを試したとき、ユーザーがAuthorizationヘッダーを入力できる各エンドポイントのパラメーターフィールド領域にAuthorizationヘッダーテキストを表示できましたが、それは私が望んだものではありませんでした。

私の状況では、有効なAuthorizationトークンを取得するために、ユーザーのCookieを使用して_/token_エンドポイントにリクエストを送信する必要がありました。だから私はこれを達成するためにいろいろなことをしました。

最初に_SwaggerConfig.cs_のコメントを外してc.BasicAuth()のコメントを外して、基本的な認証スキームをAPIスキーマに入れ、カスタムの_index.html_ページを挿入してAJAXリクエストを挿入しましたユーザーのCookieを使用してAuthorizationトークンを取得するには(以下に示す_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");

                    ...
                });
}
_

次に、 こちら に向かって、Authorizationヘッダーを挿入するようにカスタマイズするスワッシュバックル_index.html_をダウンロードします。

以下では、有効なCookieを使用して_/token_エンドポイントにAJAX呼び出しを行い、Authorizationトークンを取得して、window.swaggerUi.api.clientAuthorizations.add()で使用するためにそれをSwaggerに渡します。

_...

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トークンなどをどのように収集するかによって実装が異なることは明らかですが、それによってアイデアが得られます。特定の問題や質問がある場合はお知らせください。

*編集:実際にユーザーがAuthorizationヘッダーに入力することを望んでいたことに気づかなかった。その場合、それは非常に簡単です。 this の投稿を使用しました。単純に次のクラスを作成して作業を行います。

_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
        });
    }
}
_

次に、次のようにクラスをSwaggerConfigに追加しました:

_...
c.OperationFilter<AddRequiredHeaderParameter>();
...
_
2
hvaughan3

Swashbuckle 5では、これはStartup.cs次のファイルを使用します。

// Register the Swagger generator, defining one or more Swagger documents
services.AddSwaggerGen(c =>
{
    c.AddSecurityDefinition("bearerAuth", new OpenApiSecurityScheme
    {
        Type = SecuritySchemeType.Http,
        Scheme = "bearer",
        BearerFormat = "JWT",
        Description = "JWT Authorization header using the Bearer scheme."
    });
    c.AddSecurityRequirement(new OpenApiSecurityRequirement
    {
        {
            new OpenApiSecurityScheme
            {
                Reference = new OpenApiReference { Type = ReferenceType.SecurityScheme, Id = "bearerAuth" }
            },
            new string[] {}
        }
    });
});
1
Fred