JWT Authentication and Swagger with .Net core 3.0

后端 未结 6 738
我在风中等你
我在风中等你 2020-12-25 12:31

I am developing some Web Api with .Net core 3.0 and want to integrate it with SwashBuckle.Swagger. It is working fine, but when I add JWT authentication, it does not work as

相关标签:
6条回答
  • 2020-12-25 12:50

    If anyone is using NSwag and has landed here after searching the solution, here is the link from the official documentation.

    NSwag Enable JWT authentication

    PS: I know the original question was for SwashBuckle, but Google shows this link first when searching for NSwag as well.

    0 讨论(0)
  • 2020-12-25 12:53

    After some research, I eventually found the answer here

    Before seeing this page, I knew that I should use AddSecurityRequirement after AddSecurityDefinition because of many samples, but it was a problem that the function parameters have changed on .NET Core 3.0.

    By the way, the final answer is as below:

    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[] { } 
        } 
      });
    });
    
    0 讨论(0)
  • 2020-12-25 12:55

    Here's a solution updated for Swashbuckle.AspNetCore 5.3.2, integrated with IdentityServer4, with an API secured using a Bearer token.

    In ConfigureServices() method:

            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() method:

            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,
    
        };
    }
    
    0 讨论(0)
  • 2020-12-25 13:12

    In the accepted answer "Bearer " is required to be written before the actual token. A similar approach in which typing "Bearer " can be skipped is the following:

    c.SwaggerDoc("v1", new OpenApiInfo { Title = "Example API", Version = "v1" });
    
    c.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme
    {
        Type = SecuritySchemeType.Http,
        BearerFormat = "JWT",
        In = ParameterLocation.Header,
        Scheme = "bearer",
        Description = "Please insert JWT token into field"
    });
    
    c.AddSecurityRequirement(new OpenApiSecurityRequirement
    {
        {
            new OpenApiSecurityScheme
            {
                Reference = new OpenApiReference
                {
                    Type = ReferenceType.SecurityScheme,
                    Id = "Bearer"
                }
            },
            new string[] { }
        }
    });
    

    Here only pasting the JWT token is required for this to work.

    0 讨论(0)
  • 2020-12-25 13:12

    If you don't want to add a token manually and you want the scopes to be selectable along with passing a clientId to the identity server you can add something like this.

    I have used implicit flow, but you can configure any flow using the following mechanism:

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

    The output will be like this:

    0 讨论(0)
  • 2020-12-25 13:13

    If you are using Swagger 3.0 then it has build-in support for JWT authentication.

    You need to use ParameterLocation.Header, SecuritySchemeType.Http, bearer, and JWT in OpenApiSecurityScheme as shown below.

    After this, you wouldn't need to specify token in Bearer {token} format. Only specify the token and the security scheme will automatically apply it in the header.

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

    0 讨论(0)
提交回复
热议问题