1. ホーム
  2. c#

[解決済み] Swashbuckle.AspNetCore version 5への移行に伴うSwagger UIでのベアラ認証について

2023-05-12 13:22:08

質問

.NET Core 3 Preview 5 Web API プロジェクトで Swashbuckle のバージョン 4.0.1 から 5.0.0-rc2 への移行を試みています。

プロジェクトをコンパイルし、Swagger UIを動作させることができましたが、Bearer認証を動作させることができません。これは、私が新しい形式のセキュリティを正しく設定していないことが原因だと思います。

これは、バージョン 4 で動作していた私の古いコードです。

c.AddSecurityDefinition("Bearer", new ApiKeyScheme
{
    Description = "JWT Authorization header using the Bearer scheme. \r\n\r\n Enter 'Bearer' [space] and then your token in the text input below.\r\n\r\nExample: \"Bearer 12345abcdef\"",
    Name = "Authorization",
    In = "header",
    Type = "apiKey"
});

var security = new Dictionary<string, IEnumerable<string>>
{
    {"Bearer", new string[] { }},
};

c.AddSecurityRequirement(security);

で、これをv5用に変更したのがこれ。

c.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme
{
    Description = "JWT Authorization header using the Bearer scheme. \r\n\r\n Enter 'Bearer' [space] and then your token in the text input below.\r\n\r\nExample: \"Bearer 12345abcdef\"",
    Name = "Authorization",
    In = ParameterLocation.Header,
    Type = SecuritySchemeType.ApiKey,
    Scheme = "tomsAuth"
});

c.AddSecurityRequirement(new OpenApiSecurityRequirement
{
    {
        new OpenApiSecurityScheme
        {
            Reference = new OpenApiReference {
                Type = ReferenceType.SecurityScheme,
                Id = "tomsAuth" }
        }, new List<string>() }
});

私の問題は、おそらくコードのこの部分にあると思います。

        new OpenApiSecurityScheme
        {
            Reference = new OpenApiReference {
                Type = ReferenceType.SecurityScheme,
                Id = "tomsAuth" }
        }, new List<string>() }

この部分には、おそらく "Bearer" がどこかに入っているはずだと思うのですが、どこでしょう?

追加情報

そもそも、JWT認証の設定はこんな感じです。 このコードは変更されておらず、Swashbuckle 4.0.1 を使用していたときに動作していました。

    var appSettings = appSettingsSection.Get<AppSettings>();
    var key = Encoding.ASCII.GetBytes(appSettings.Secret);

    services.AddAuthentication(x =>
    {
        x.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
        x.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
    })
    .AddJwtBearer(x =>
    {
        x.Events = new JwtBearerEvents
        {
            OnTokenValidated = context =>
            {
                var userService = context.HttpContext.RequestServices.GetRequiredService<IApiUserService>();
                var userId = int.Parse(context.Principal.Identity.Name);
                var user = userService.GetById(userId);
                if (user == null)
                {
                    // return unauthorized if user no longer exists
                    context.Fail("Unauthorized");
                }

                return Task.CompletedTask;
            }
        };
        x.RequireHttpsMetadata = false;
        x.SaveToken = true;
        x.TokenValidationParameters = new TokenValidationParameters
        {
            ValidateIssuerSigningKey = true,
            IssuerSigningKey = new SymmetricSecurityKey(key),
            ValidateIssuer = false,
            ValidateAudience = false
        };
    });

どのように解決するのですか?

試行錯誤の結果、最終的にこれが動作するようになりました。これは、私のために動作するコードです。

c.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme
{
    Description =
        "JWT Authorization header using the Bearer scheme. \r\n\r\n Enter 'Bearer' [space] and then your token in the text input below.\r\n\r\nExample: \"Bearer 12345abcdef\"",
    Name = "Authorization",
    In = ParameterLocation.Header,
    Type = SecuritySchemeType.ApiKey,
    Scheme = "Bearer"
});

c.AddSecurityRequirement(new OpenApiSecurityRequirement()
{
    {
        new OpenApiSecurityScheme
        {
            Reference = new OpenApiReference
            {
                Type = ReferenceType.SecurityScheme,
                Id = "Bearer"
            },
            Scheme = "oauth2",
            Name = "Bearer",
            In = ParameterLocation.Header,

        },
        new List<string>()
    }
});

おそらく、実際には明示的に設定する必要のないプロパティがそこに設定されているのではないかと思いますが、上記は私のために動作しています。