JWT-Authentifizierung und Swagger mit .Net Core 3.0


10

Ich entwickle einige Web-APIs mit .Net Core 3.0 und möchte sie in SwashBuckle.Swagger integrieren. Es funktioniert einwandfrei, aber wenn ich die JWT-Authentifizierung hinzufüge, funktioniert es nicht wie erwartet. Dazu habe ich den folgenden Code hinzugefügt:

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

        });

Nach dem Hinzufügen der AddSecurityDefinitionFunktion wird die Schaltfläche "Autorisieren" angezeigt. Wenn ich darauf klicke, wird das folgende Formular angezeigt: Geben Sie hier die Bildbeschreibung ein

Dann tippe ich Bearer WhatEverApiKeyIsfgdgdgdg845734987fgdhgiher635kjh: Nachdem ich es getan habe, erwarte ich, dass es authorization: Bearer WhatEverApiKeyIsfgdgdgdg845734987fgdhgiher635kjhim Header der Anfrage angezeigt wird, wenn ich eine Anfrage von Swagger an die Web-API sende. Die Berechtigung wird jedoch nicht zum Anforderungsheader hinzugefügt. Ich benutze SwashBuckle.Swagger (5.0.0-rc3). Bitte beachten Sie, dass es viele Beispiele gibt, die unter .net Core 2.0 einwandfrei funktionieren, aber die Swashbuckle-Swagger-Funktionen wurden in der neuesten Version geändert, sodass ich diese Beispiele nicht verwenden kann.



Auf den von Ihnen erwähnten Link gibt es keine Antwort. Auch .net Core 3.0 ist etwas anders.
Mehrdad Babaki

Die Antwort ist .AddSecurityRequirement(global) oder .Security(auf Operationsebene) hinzuzufügen - wie in den Antworten auf die verknüpfte Frage erläutert. AddSecurityDefinitionallein reicht nicht aus.
Helen

Ich fügte hinzu, aber nichts änderte sich. Ich denke, deshalb wird es nicht als Antwort ausgewählt.
Mehrdad Babaki

Ich habe dies kürzlich auf eine andere Frage beantwortet. Schauen Sie hier: stackoverflow.com/a/57872872/3952573
Pavlos

Antworten:


33

Nach einigen Recherchen fand ich schließlich die Antwort hier

Bevor Sie diese Seite sehen, wusste ich , dass ich sollte AddSecurityRequirementnach AddSecurityDefinitionwegen der vielen Proben, aber es war ein Problem , dass die Funktionsparameter auf .NET - Core 3.0 geändert haben.

Die endgültige Antwort lautet übrigens wie folgt:

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

Vielen Dank, es funktioniert gut mit mir
Anas Al-Qudah

2
Dies hat funktioniert. Tipp: Vergessen Sie nicht, "Bearer" vor dem eigentlichen Token zu schreiben. Und es ist ein bisschen ärgerlich, dass Swagger immer autorisiert sagt, egal was Sie in die Textbox schreiben ... Danke!
CodeHacker

Dies funktioniert auf Net Core 3 und Swagger
Ericpap

Wer ein Leben rettet, rettet die Welt. Du hast mein Leben gerettet ;-) Danke
Vahid Farahmandian

6

Wenn Sie Swagger 3.0 verwenden, wird die JWT-Authentifizierung bereits unterstützt.

Sie müssen ParameterLocation.Header, SecuritySchemeType.Http, Bearer und JWT in OpenApiSecurityScheme wie unten gezeigt verwenden.

Danach müssen Sie kein Token im Bearer {Token} -Format angeben . Geben Sie nur das Token an, und das Sicherheitsschema wendet es automatisch im Header an.

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

Geben Sie hier die Bildbeschreibung ein


Vielen Dank! Nach vielen Posts, die bei mir nicht funktionierten, hat diese Methode funktioniert !!
Matt Casto

2

Wenn Sie ein Token nicht manuell hinzufügen möchten und die Bereiche auswählbar sein sollen und eine Client-ID an den Identitätsserver übergeben werden soll, können Sie Folgendes hinzufügen.

Ich habe den impliziten Fluss verwendet, aber Sie können jeden Fluss mithilfe des folgenden Mechanismus konfigurieren:

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

Die Ausgabe sieht folgendermaßen aus:

Geben Sie hier die Bildbeschreibung ein


1

Hier ist eine für Swashbuckle.AspNetCore 5.3.2 aktualisierte Lösung, die in IdentityServer4 integriert ist und deren API mit einem Bearer-Token gesichert ist.

In ConfigureServices()Methode:

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

In Configure()Methode:

        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,

    };
}

Dies ist ein Lebensretter. Es funktioniert auch für implizite Flows, bei denen ich das Passwort im Flows-Setup in Implicit geändert habe. Vielen Dank!
Larsbj

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.