การตรวจสอบ JWT และ Swagger ด้วย. Net core 3.0


10

ฉันกำลังพัฒนา Web 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 มีการเปลี่ยนแปลงในเวอร์ชั่นล่าสุดดังนั้นฉันจึงไม่สามารถใช้ตัวอย่างนั้นได้


ซ้ำซ้อนที่เป็นไปได้ของการอนุญาตสำหรับผู้ถือ JWT ใน Swashbuckle .NET Core 2
Helen

ในลิงค์ที่คุณกล่าวถึงไม่มีคำตอบ นอกจากนี้. net core 3.0 นั้นแตกต่างกันเล็กน้อย
Mehrdad Babaki

คำตอบคือการเพิ่ม.AddSecurityRequirement(ทั่วโลก) หรือ.Security(ในระดับปฏิบัติการ) - ตามที่อธิบายไว้ในคำตอบของคำถามที่เชื่อมโยง AddSecurityDefinitionเพียงอย่างเดียวไม่เพียงพอ
เฮเลน

ฉันเพิ่ม แต่ไม่มีอะไรเปลี่ยนแปลง ฉันคิดว่านั่นเป็นเหตุผลที่มันไม่ได้รับเลือกเป็นคำตอบ
Mehrdad Babaki

ฉันตอบคำถามนี้เมื่อเร็ว ๆ นี้มีคำถามอื่นดูที่นี่: 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[] { } 
    } 
  });
});

ขอบคุณมากมันใช้ได้ดีกับฉัน
Anas Al-Qudah

2
สิ่งนี้ใช้ได้ผล .. เคล็ดลับ: อย่าลืมเขียน "Bearer" หน้าโทเค็นจริง และมันก็น่ารำคาญนิดหน่อยที่ผยองมักจะบอกว่าได้รับอนุญาตเสมอไม่ว่าคุณจะเขียนอะไรใน Textbox ... ขอบคุณ!
CodeHacker

มันใช้งานได้กับเน็ตคอร์ 3 และกร่าง
ericpap

ใครก็ตามที่ช่วยชีวิตจะบันทึกโลก คุณช่วยชีวิตฉันไว้ ;-) ขอบคุณ
Vahid Farahmandian

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

ป้อนคำอธิบายรูปภาพที่นี่


ขอบคุณ! หลังจากโพสต์มากมายที่ไม่ได้ผลสำหรับฉันวิธีนี้ก็ทำ !!
Matt Casto

2

หากคุณไม่ต้องการเพิ่มโทเค็นด้วยตนเองและคุณต้องการให้ขอบเขตสามารถเลือกได้พร้อมกับส่งรหัสลูกค้าไปยังเซิร์ฟเวอร์ข้อมูลประจำตัวคุณสามารถเพิ่มสิ่งนี้ได้

ฉันใช้โฟลว์ทางอ้อม แต่คุณสามารถกำหนดค่าโฟลว์ใด ๆ โดยใช้กลไกต่อไปนี้:

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 เช่นกัน

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.