Autenticação e Swagger JWT com .Net core 3.0

10

Estou desenvolvendo alguma API da Web com o .Net core 3.0 e quero integrá-la ao SwashBuckle.Swagger. Está funcionando bem, mas quando adiciono a autenticação JWT, não funciona conforme o esperado. Para fazer isso, adicionei o código abaixo:

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

        });

Após adicionar a AddSecurityDefinitionfunção, vejo o botão Autorizar e, quando clico nele, vejo o formulário abaixo: insira a descrição da imagem aqui

Então digito Bearer WhatEverApiKeyIsfgdgdgdg845734987fgdhgiher635kjh: Depois de fazer isso, espero ver authorization: Bearer WhatEverApiKeyIsfgdgdgdg845734987fgdhgiher635kjhno cabeçalho da solicitação, quando enviar uma solicitação para a API da Web do Swagger. Mas a autorização não é adicionada ao cabeçalho da solicitação. Estou usando o SwashBuckle.Swagger (5.0.0-rc3). Observe que existem muitos exemplos que funcionam bem no .net core 2.0, mas as funções do swashbuckle swagger foram alteradas na versão mais recente, portanto não posso usá-los.

Mehrdad Babaki
fonte
No link que você mencionou, não há resposta. Além disso, o .net core 3.0 é um pouco diferente.
Mehrdad Babaki
A resposta é adicionar .AddSecurityRequirement(globalmente) ou .Security(no nível da operação) - conforme explicado nas respostas à pergunta vinculada. AddSecurityDefinitionsozinho não é suficiente.
Helen
Eu adicionei, mas nada mudou. Eu acho que é por isso que não está selecionado como resposta.
Mehrdad Babaki 01/10/19
Eu respondi isso recentemente em outra pergunta, dê uma olhada aqui: stackoverflow.com/a/57872872/3952573
Pavlos

Respostas:

33

Depois de alguma pesquisa, eu finalmente encontrei a resposta aqui

Antes de ver esta página, eu sabia que deveria usá-lo AddSecurityRequirementpor AddSecurityDefinitioncausa de muitos exemplos, mas era um problema que os parâmetros de função foram alterados no .NET Core 3.0.

A propósito, a resposta final é a seguinte:

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[] { } 
    } 
  });
});
Mehrdad Babaki
fonte
Muito obrigado, é um trabalho muito bem comigo
Anas Al-Qudah
2
Isso funcionou .. Dica: não se esqueça de escrever "Portador" antes do token real. E é um pouco irritante que a arrogância sempre diga autorizada, não importa o que você escreva na caixa de texto ... Obrigado!
CodeHacker 8/11/19
Isso funciona no net core 3 e no swagger
ericpap 07/01
Quem salva uma vida salva o mundo. Você salvou minha vida ;-) thx
Vahid Farahmandian
6

Se você estiver usando o Swagger 3.0, ele possui suporte embutido para autenticação JWT.

Você precisa usar ParameterLocation.Header, SecuritySchemeType.Http, portador e JWT no OpenApiSecurityScheme, como mostrado abaixo.

Depois disso, você não precisaria especificar o token no formato Bearer {token} . Especifique apenas o token e o esquema de segurança o aplicará automaticamente no cabeçalho.

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

insira a descrição da imagem aqui

ameya
fonte
Obrigado! Depois de muitas postagens que não funcionaram para mim, esse método funcionou !!
Matt Casto
2

Se você não deseja adicionar um token manualmente e deseja que os escopos sejam selecionáveis ​​juntamente com a transmissão de um clientId para o servidor de identidade, você pode adicionar algo assim.

Eu usei fluxo implícito, mas você pode configurar qualquer fluxo usando o seguinte mecanismo:

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

A saída será assim:

insira a descrição da imagem aqui

Prabhanjan Kumar Mahapatra
fonte
1

Aqui está uma solução atualizada para o Swashbuckle.AspNetCore 5.3.2, integrado ao IdentityServer4, com uma API protegida usando um token Bearer.

No ConfigureServices()método:

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

No Configure()método:

        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,

    };
}
Paul Taylor
fonte
Este é um salva-vidas. Também funciona para o fluxo implícito, onde eu mudei a Senha para Implícita na configuração do Fluxos. Muito obrigado!
Larsbj 22/04
0

Se alguém estiver usando o NSwag e chegou aqui depois de pesquisar a solução, aqui está o link da documentação oficial.

NSwag Ativar autenticação JWT

PS: Eu sei que a pergunta original era para o SwashBuckle, mas o Google mostra esse link primeiro ao pesquisar pelo NSwag também.

Prateek Kumar Dalbehera
fonte