Authentification JWT et Swagger avec .Net core 3.0

10

Je développe une API Web avec .Net core 3.0 et je souhaite l'intégrer à SwashBuckle.Swagger. Cela fonctionne bien, mais lorsque j'ajoute l'authentification JWT, cela ne fonctionne pas comme prévu. Pour ce faire, j'ai ajouté le code ci-dessous:

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

        });

Après avoir ajouté une AddSecurityDefinitionfonction, je peux voir le bouton Autoriser et quand je clique dessus, je vois le formulaire ci-dessous: entrez la description de l'image ici

Ensuite, je tape Bearer WhatEverApiKeyIsfgdgdgdg845734987fgdhgiher635kjh, Après l'avoir fait, je m'attends à voir authorization: Bearer WhatEverApiKeyIsfgdgdgdg845734987fgdhgiher635kjhdans l'en-tête de la demande, lorsque j'envoie une demande à l'API Web de Swagger. Mais l'autorisation n'est pas ajoutée à l'en-tête de la demande. J'utilise SwashBuckle.Swagger (5.0.0-rc3). Veuillez noter qu'il existe de nombreux exemples qui fonctionnent correctement sur .net core 2.0, mais les fonctions de swagger Swashbuckle ont changé sur la dernière version, donc je ne peux pas utiliser ces exemples.

Mehrdad Babaki
la source
Sur le lien que vous avez mentionné, il n'y a pas de réponse. De plus, .net core 3.0 est légèrement différent.
Mehrdad Babaki
La réponse est d'ajouter .AddSecurityRequirement(globalement) ou .Security(au niveau de l'opération) - comme expliqué dans les réponses à la question liée. AddSecurityDefinitionseul ne suffit pas.
Helen
J'ai ajouté mais rien n'a changé. Je pense que c'est pourquoi il n'est pas sélectionné comme réponse.
Mehrdad Babaki
J'ai répondu récemment à une autre question, jetez un œil ici: stackoverflow.com/a/57872872/3952573
Pavlos

Réponses:

33

Après quelques recherches, j'ai finalement trouvé la réponse ici

Avant de voir cette page, je savais que je devrais l'utiliser AddSecurityRequirementaprès à AddSecurityDefinitioncause de nombreux exemples, mais c'était un problème que les paramètres de la fonction ont changé sur .NET Core 3.0.

Soit dit en passant, la réponse finale est la suivante:

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
la source
Merci beaucoup, ça marche très bien avec moi
Anas Al-Qudah
2
Cela a fonctionné. Astuce: n'oubliez pas d'écrire "Bearer" avant le jeton réel. Et c'est un peu ennuyeux que le fanfaron dise toujours autorisé, peu importe ce que vous écrivez dans la zone de texte ... Merci!
CodeHacker
Cela fonctionne sur net core 3 et swagger
ericpap
Celui qui sauve une vie sauve le monde. Vous m'avez sauvé la vie ;-) thx
Vahid Farahmandian
6

Si vous utilisez Swagger 3.0, il dispose d'une prise en charge intégrée pour l'authentification JWT.

Vous devez utiliser ParameterLocation.Header, SecuritySchemeType.Http, bearer et JWT dans OpenApiSecurityScheme comme indiqué ci-dessous.

Après cela, vous n'aurez plus besoin de spécifier de jeton au format Bearer {token} . Spécifiez uniquement le jeton et le schéma de sécurité l'appliquera automatiquement dans l'en-tête.

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

entrez la description de l'image ici

ameya
la source
Je vous remercie! Après de nombreux messages qui n'ont pas fonctionné pour moi, cette méthode a fonctionné !!
Matt Casto
2

Si vous ne souhaitez pas ajouter un jeton manuellement et que vous souhaitez que les étendues soient sélectionnables et que vous passiez un clientId au serveur d'identité, vous pouvez ajouter quelque chose comme ceci.

J'ai utilisé un flux implicite, mais vous pouvez configurer n'importe quel flux à l'aide du mécanisme suivant:

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

La sortie sera comme ceci:

entrez la description de l'image ici

Prabhanjan Kumar Mahapatra
la source
1

Voici une solution mise à jour pour Swashbuckle.AspNetCore 5.3.2, intégrée à IdentityServer4, avec une API sécurisée à l'aide d'un jeton Bearer.

En ConfigureServices()méthode:

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

En Configure()méthode:

        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
la source
C'est un épargnant de vie. Il fonctionne également pour le flux implicite où j'ai changé le mot de passe en implicite dans la configuration des flux. Merci beaucoup!
Larsbj
0

Si quelqu'un utilise NSwag et a atterri ici après avoir recherché la solution, voici le lien de la documentation officielle.

NSwag Activer l'authentification JWT

PS: Je sais que la question d'origine était pour SwashBuckle, mais Google affiche également ce lien lors de la recherche de NSwag.

Prateek Kumar Dalbehera
la source