Автентифікація 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у заголовку запиту, коли я надсилаю запит на веб-апі від 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
Павлос

Відповіді:


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[] { } 
    } 
  });
});

Велике спасибі, зі мною це добре працює
Anas Al-Qudah

2
Це спрацювало. Порада: не забудьте написати "Носій" перед фактичним маркером. І трохи прикро, що шахрай завжди говорить авторизовано, незалежно від того, що ви пишете в Textbox ... Дякую!
CodeHacker

Це працює на мережевому ядрі 3 та
swagger

Хто рятує життя, той спасає світ. Ти врятував мені життя ;-) thx
Вахід Фарахмандіан

6

Якщо ви використовуєте Swagger 3.0, він має вбудовану підтримку аутентифікації JWT.

Вам потрібно використовувати ParameterLocation.Header, SecuritySchemeType.Http, носій і JWT у OpenApiSecurityScheme, як показано нижче.

Після цього вам не потрібно буде вказувати маркер у форматі носія {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);

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


Дякую! Після багатьох постів, які не працювали для мене, цей метод зробив !!
Метт Касто

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.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.