Аутентификация JWT и Swagger с .Net core 3.0

10

Я занимаюсь разработкой веб-API с .Net core 3.0 и хочу интегрировать его с SwashBuckle.Swagger. Он работает нормально, но когда я добавляю аутентификацию JWT, она не работает так, как я ожидаю. Для этого я добавил код ниже:

  services.AddSwaggerGen(c =>
        {
            c.SwaggerDoc("v1", new Microsoft.OpenApi.Models.OpenApiInfo { Title = "My Web 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
            });

        });

После добавления AddSecurityDefinitionфункции я вижу кнопку «Авторизоваться», и когда я нажимаю на нее, я вижу форму ниже: введите описание изображения здесь

Затем я набираю Bearer WhatEverApiKeyIsfgdgdgdg845734987fgdhgiher635kjh, После этого я ожидаю увидеть authorization: Bearer WhatEverApiKeyIsfgdgdgdg845734987fgdhgiher635kjhв заголовке запроса, когда отправляю запрос в Web Api от Swagger. Но авторизация не добавляется в заголовок запроса. Я использую SwashBuckle.Swagger (5.0.0-rc3). Обратите внимание, что есть много примеров, которые отлично работают на .net core 2.0, но функции Swashbuckle swagger изменились в последней версии, поэтому я не могу использовать эти примеры.

Мехрдад Бабаки
источник
На указанную вами ссылку ответа нет. Также .net core 3.0 немного отличается.
Мехрдад Бабаки
Ответ должен добавить .AddSecurityRequirement(глобально) или .Security(на уровне операций) - как объяснено в ответах на связанный вопрос. AddSecurityDefinitionодного недостаточно.
Хелен
Я добавил, но ничего не изменилось. Я думаю, именно поэтому он не выбран в качестве ответа.
Мехрдад Бабаки
Я ответил на это недавно на другой вопрос, посмотрите здесь: stackoverflow.com/a/57872872/3952573
Pavlos

Ответы:

33

После некоторых исследований я в конце концов нашел ответ здесь

До того, как я увидел эту страницу, я знал, что мне следует использовать AddSecurityRequirementпосле этого AddSecurityDefinitionиз-за большого количества примеров, но проблема в том, что параметры функции изменились в .NET Core 3.0.

Кстати, окончательный ответ, как показано ниже:

services.AddSwaggerGen(c =>
{
  c.SwaggerDoc("v1", new OpenApiInfo { 
    Title = "My API", 
    Version = "v1" 
  });
  c.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme {
    In = ParameterLocation.Header, 
    Description = "Please insert JWT with Bearer into field",
    Name = "Authorization",
    Type = SecuritySchemeType.ApiKey 
  });
  c.AddSecurityRequirement(new OpenApiSecurityRequirement {
   { 
     new OpenApiSecurityScheme 
     { 
       Reference = new OpenApiReference 
       { 
         Type = ReferenceType.SecurityScheme,
         Id = "Bearer" 
       } 
      },
      new string[] { } 
    } 
  });
});
Мехрдад Бабаки
источник
Большое спасибо, у меня все хорошо
Анас Аль-Куда,
2
Это сработало. Совет: не забудьте написать «Носитель» перед фактическим токеном. И это немного раздражает, что чванство всегда говорит, что авторизовано, независимо от того, что вы пишете в текстовом поле ... Спасибо!
CodeHacker
Это работает на чистом ядре 3 и
чванстве
Тот, кто спасает жизнь, спасает мир. Ты спас мне жизнь ;-) thx
Вахид Фарамандян
6

Если вы используете Swagger 3.0, он имеет встроенную поддержку аутентификации JWT.

Вам необходимо использовать ParameterLocation.Header, SecuritySchemeType.Http, bearer и JWT в OpenApiSecurityScheme, как показано ниже.

После этого вам не нужно указывать токен в формате Bearer {token} . Укажите только токен, и схема безопасности автоматически применит его в заголовке.

// Bearer token authentication
OpenApiSecurityScheme securityDefinition = new OpenApiSecurityScheme()
{
    Name = "Bearer",
    BearerFormat = "JWT",
    Scheme = "bearer",
    Description = "Specify the authorization token.",
    In = ParameterLocation.Header,
    Type = SecuritySchemeType.Http,
};
c.AddSecurityDefinition("jwt_auth", securityDefinition);

// Make sure swagger UI requires a Bearer token specified
OpenApiSecurityScheme securityScheme = new OpenApiSecurityScheme()
{
    Reference = new OpenApiReference()
    {
        Id = "jwt_auth",
        Type = ReferenceType.SecurityScheme
    }
};
OpenApiSecurityRequirement securityRequirements = new OpenApiSecurityRequirement()
{
    {securityScheme, new string[] { }},
};
c.AddSecurityRequirement(securityRequirements);

введите описание изображения здесь

Ameya
источник
Спасибо! После многих сообщений, которые не работали для меня, этот метод сделал !!
Мэтт Касто
2

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

Я использовал неявный поток, но вы можете настроить любой поток, используя следующий механизм:

options.AddSecurityDefinition("oauth2", new OpenApiSecurityScheme()
{
  Flows = new OpenApiOAuthFlows
  {
    Implicit = new OpenApiOAuthFlow
    {                            
      AuthorizationUrl = new Uri("http://localhost"),
      TokenUrl = new Uri("http://localhost"),
      Scopes = new Dictionary<string, string>
      {
        { "Foundation API", "FoundationApi" }
      }
    }
  },
  In = ParameterLocation.Header,                    
  Name = "Authorization",
  Type = SecuritySchemeType.OAuth2                    
});

Вывод будет таким:

введите описание изображения здесь

Прабханджан Кумар Махапатра
источник
1

Вот обновленное решение для Swashbuckle.AspNetCore 5.3.2, интегрированное с IdentityServer4, с API-интерфейсом, защищенным с помощью токена Bearer.

В ConfigureServices()методе:

        services.AddSwaggerGen(options =>
        {
            options.SwaggerDoc("v1", new OpenApiInfo { Title = "My API", Version = "v1" });
            options.AddSecurityDefinition("Bearer", SecuritySchemes.BearerScheme(Configuration));
            options.AddSecurityRequirement(new OpenApiSecurityRequirement()
            {
                { SecuritySchemes.OAuthScheme, new List<string>() }
            });
        });

В Configure()методе:

        app.UseSwaggerUI(options =>
        {
            options.SwaggerEndpoint("/My.Api/swagger/v1/swagger.json", "My API V1");
            options.OAuthClientId(Clients.TestClient);
            options.OAuthAppName("My Api - Swagger");
            options.OAuthClientSecret(Configuration["TestClientSecret"]);
        });

internal static class SecuritySchemes
{
    public static OpenApiSecurityScheme BearerScheme(IConfiguration config) => new OpenApiSecurityScheme
    {
        Type = SecuritySchemeType.OAuth2,
        Description = "Standard authorisation using the Bearer scheme. Example: \"bearer {token}\"",
        In = ParameterLocation.Header,
        Name = "Authorization",
        Scheme = "Bearer",
        OpenIdConnectUrl = new System.Uri($"{config["TokenServerUrl"]}.well-known/openid-configuration"),
        BearerFormat = "JWT",
        Flows = new OpenApiOAuthFlows
        {
            Password = new OpenApiOAuthFlow
            {
                AuthorizationUrl = new System.Uri($"{config["TokenServerUrl"]}connect/authorize"),
                Scopes = new Dictionary<string, string>
                    {
                        { Scopes.Api, "My Api" }
                    },
                TokenUrl = new System.Uri($"{config["TokenServerUrl"]}connect/token")
            }
        }
    };

    public static OpenApiSecurityScheme OAuthScheme => new OpenApiSecurityScheme
    {
        Reference = new OpenApiReference
        {
            Type = ReferenceType.SecurityScheme,
            Id = "Bearer"
        },
        Scheme = "oauth2",
        Name = "Bearer",
        In = ParameterLocation.Header,

    };
}
Пол Тейлор
источник
Это спасатель жизни. Это также работает для неявного потока, где я изменил пароль на неявный в настройке потоков. Огромное спасибо!
Larsbj
0

Если кто-то использует NSwag и приземлился здесь после поиска решения, вот ссылка из официальной документации.

NSwag Включить аутентификацию JWT

PS: я знаю, что оригинальный вопрос был о SwashBuckle, но Google сначала показывает эту ссылку при поиске NSwag.

Пратик Кумар Далбехера
источник