161

I have a Web API (ASP.NET Core) and I am trying to adjust the swagger to make the calls from it. The calls must contains the Authorization header and I am using Bearer authentication. The calls from third party apps like Postman, etc. go fine. But I am having the issue with setting up the headers for swagger (for some reason I don't receive the headers). This is how it looks like now:

  "host": "localhost:50352",
  "basePath": "/" ,
  "schemes": [
    "http",
    "https"
  ],
 "securityDefinitions":  {
    "Bearer": {
      "name": "Authorization",
      "in": "header",
      "type": "apiKey",
      "description": "HTTP/HTTPS Bearer"
    }
  },
  "paths": { 
    "/v1/{subAccountId}/test1": {
      "post": {
        "tags": [
          "auth"
        ],
        "operationId": "op1",
        "consumes": ["application/json", "application/html"],
        "produces": ["application/json", "application/html"],
        "parameters": [
          {
            "name": "subAccountId",
            "in": "path",
            "required": true,
            "type": "string"
          }
        ],
        "security":[{
          "Bearer": []
        }],
        "responses": {
          "204": {
            "description": "No Content"
          },
          "400": {
            "description": "BadRequest",
            "schema": {
              "$ref": "#/definitions/ErrorResponse"
            }
          },
          "401": {
            "description": "Unauthorized",
            "schema": {
              "$ref": "#/definitions/ErrorResponse"
            }
          },
          "500": {
            "description": "InternalServerError",
            "schema": {
              "$ref": "#/definitions/ErrorResponse"
            }
          }
        },
        "deprecated": false
      }
    },
J.Doe
  • 1,701
  • 2
  • 10
  • 4
  • I did it with firebase https://stackoverflow.com/questions/61540706/configure-swagger-authentication-with-firebase-google-in-net-core/61540707#61540707 – Farshid May 01 '20 at 10:32

7 Answers7

248

ApiKeyScheme was deprecated, in version 5 you can use like this:

services.AddSwaggerGen(c =>
  {
    c.SwaggerDoc("v1", new Info { Title = "You api title", Version = "v1" });
    c.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme
      {
        Description = @"JWT Authorization header using the Bearer scheme. \r\n\r\n 
                      Enter 'Bearer' [space] and then your token in the text input below.
                      \r\n\r\nExample: 'Bearer 12345abcdef'",
         Name = "Authorization",
         In = ParameterLocation.Header,
         Type = SecuritySchemeType.ApiKey,
         Scheme = "Bearer"
       });

    c.AddSecurityRequirement(new OpenApiSecurityRequirement()
      {
        {
          new OpenApiSecurityScheme
          {
            Reference = new OpenApiReference
              {
                Type = ReferenceType.SecurityScheme,
                Id = "Bearer"
              },
              Scheme = "oauth2",
              Name = "Bearer",
              In = ParameterLocation.Header,

            },
            new List<string>()
          }
        });
    var xmlFile = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml";
    var xmlPath = Path.Combine(AppContext.BaseDirectory, xmlFile);
    c.IncludeXmlComments(xmlPath);
});
Jesse
  • 3,522
  • 6
  • 25
  • 40
Alex
  • 8,908
  • 28
  • 103
  • 157
  • 21
    Can confirm this is working like a charm for .NET Core 3.0 - the code I wrote when using .NET Core 2.2 no longer worked after the upgrade and this is what I needed – Horkrine Nov 26 '19 at 15:25
  • 13
    Minor points: i) I needed to use
    instead of \r\n for the message to display correctly. ii) instead of new Info { ... I needed new OpenApiInfo {Title ... . [using swashbuckle.aspnetcore 5.0.0 and Microsoft.OpenApi 1.1.4 [.net core 3.1]]
    – ubienewbie Feb 18 '20 at 18:35
  • 1
    What about: 1. AllowAnonymous 2. Roles? – Hassan Faghihi Mar 14 '20 at 08:53
  • This works for me but the description "\r\n" part is not working... – Ben Jul 03 '20 at 04:49
  • The combination of `SecuritySchemeType.ApiKey` & `Scheme="Bearer"` seems to not provide any scheme value in the parameter of the Authorization header. Any scheme value used with `SecuritySchemeType.ApiKey` results in a header with a format of `{"Authorization","value"}`. If `{"Authorization","scheme value"}` is desired, then `SecuritySchemeType.Http` & `Scheme="Bearer"` should be used. – Josh Gust Oct 09 '20 at 23:13
  • 1
    @Ben It gets turned into HTML so you can use
    instead of "\r\n"
    – Timothy Beamish Feb 24 '21 at 19:40
  • Works with .net 6 too. – Alamakanambra Apr 18 '22 at 08:31
147

First of all, you can use Swashbuckle.AspNetCore nuget package for auto generating your swagger definition. (tested on 2.3.0)

After you've installed package, setup it in Startup.cs in method ConfigureServices

services.AddSwaggerGen(c => {
    c.SwaggerDoc("v1", new Info { Title = "You api title", Version = "v1" });
    c.AddSecurityDefinition("Bearer",
        new ApiKeyScheme { In = "header",
          Description = "Please enter into field the word 'Bearer' following by space and JWT", 
          Name = "Authorization", Type = "apiKey" });
    c.AddSecurityRequirement(new Dictionary<string, IEnumerable<string>> {
        { "Bearer", Enumerable.Empty<string>() },
    });

});

Then you can use Authorize button at the top right of the page.

At least you can try to use this package to generate valid swagger definition

Ashish Kamble
  • 2,555
  • 3
  • 21
  • 29
Vadym K
  • 1,647
  • 1
  • 10
  • 14
  • Good answer but when I do that with ABP boilerplate, it doesn't work with Dynamic Web Api (https://aspnetboilerplate.com/Pages/Documents/Dynamic-Web-API) – Kénium Aug 25 '17 at 11:32
  • 6
    @VadimK That worked perfectly until I upgraded to .NET Core 2.0 – monty Oct 12 '17 at 09:22
  • 13
    In the case this helps, in the Auth box , in the value input you have to put exactly the Auth header not only the JWT (in the case you are using it). This means : Bearer your_token_jwt – gatsby Nov 16 '18 at 11:09
  • 2
    Make sure you prefix you token with "Bearer". I was not using Bearer your_token_jwt – PUG May 03 '19 at 05:20
  • And what they did for: 1. AllowAnonymous 2. Roles? – Hassan Faghihi Mar 14 '20 at 08:54
  • 1
    i would like to skip that ```bearer``` prefix. .how to programmatically catch the token value and prepend it with ```bearer ``` in case its missing? – ulkas May 02 '22 at 14:45
  • What is ApiKeyScheme ? – toha Apr 28 '23 at 02:12
  • This is working at .net 5. For ApiKeyScheme I do not know what is it? I use "Bearer" for that lost enumeration class. – toha Apr 28 '23 at 02:38
123

TIP!

To avoid always write the keyword Bearer on the Swagger(a.k.a Swashbuckle) auth dialog, like: "bearer xT1...", you can use the code/config below on ConfigureServices(...) method at your Startup class:

using Microsoft.OpenApi.Models;
...


services.AddSwaggerGen(setup =>
{
    // Include 'SecurityScheme' to use JWT Authentication
    var jwtSecurityScheme = new OpenApiSecurityScheme
    {
        BearerFormat = "JWT",
        Name = "JWT Authentication",
        In = ParameterLocation.Header,
        Type = SecuritySchemeType.Http,
        Scheme = JwtBearerDefaults.AuthenticationScheme,
        Description = "Put **_ONLY_** your JWT Bearer token on textbox below!",

        Reference = new OpenApiReference
        {
            Id = JwtBearerDefaults.AuthenticationScheme,
            Type = ReferenceType.SecurityScheme
        }
    };

    setup.AddSecurityDefinition(jwtSecurityScheme.Reference.Id, jwtSecurityScheme);

    setup.AddSecurityRequirement(new OpenApiSecurityRequirement
    {
        { jwtSecurityScheme, Array.Empty<string>() }
    });

});

We can make this, only by changing the Type property of the OpenApiSecurityScheme class to:

Type = SecuritySchemeType.Http

instead

Type = SecuritySchemeType.ApiKey.

:)

Like this...

Packages:

Swashbuckle.AspNetCore(5.6.3)
Swashbuckle.AspNetCore.SwaggerUI(5.6.3)

I'am using .NET Core 3.1.

starball
  • 20,030
  • 7
  • 43
  • 238
Igor
  • 3,573
  • 4
  • 33
  • 55
43

Using ASP.Net Core 3.1, here's what worked for me:

services.AddSwaggerGen(s =>
        {
            s.SwaggerDoc("v1", new OpenApiInfo
            {
                Version = "v1",
                Title = "Chat API",
                Description = "Chat API Swagger Surface",
                Contact = new OpenApiContact
                {
                    Name = "João Victor Ignacio",
                    Email = "ignaciojvig@gmail.com",
                    Url = new Uri("https://www.linkedin.com/in/ignaciojv/")
                },
                License = new OpenApiLicense
                {
                    Name = "MIT",
                    Url = new Uri("https://github.com/ignaciojvig/ChatAPI/blob/master/LICENSE")
                }

            });

            s.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme
            {
                Description = "JWT Authorization header using the Bearer scheme (Example: 'Bearer 12345abcdef')",
                Name = "Authorization",
                In = ParameterLocation.Header,
                Type = SecuritySchemeType.ApiKey,
                Scheme = "Bearer"
            });

            s.AddSecurityRequirement(new OpenApiSecurityRequirement
            {
                {
                    new OpenApiSecurityScheme
                    {
                        Reference = new OpenApiReference
                        {
                            Type = ReferenceType.SecurityScheme,
                            Id = "Bearer"
                        }
                    },
                    Array.Empty<string>()
                }
            });

        });
João Ignacio
  • 654
  • 8
  • 7
13

Update 17.12.2022

in case someone has problems adding JWT to .Net 7 the next code worked for me, should work in .Net 6 as well

builder.Services.AddSwaggerGen(c =>
{
    c.SwaggerDoc("v1", new OpenApiInfo { Title = "Test01", Version = "v1" });

    c.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme()
    {
        Name = "Authorization",
        Type = SecuritySchemeType.ApiKey,
        Scheme = "Bearer",
        BearerFormat = "JWT",
        In = ParameterLocation.Header,
        Description = "JWT Authorization header using the Bearer scheme."

    });
    c.AddSecurityRequirement(new OpenApiSecurityRequirement
                {
                    {
                          new OpenApiSecurityScheme
                          {
                              Reference = new OpenApiReference
                              {
                                  Type = ReferenceType.SecurityScheme,
                                  Id = "Bearer"
                              }
                          },
                         new string[] {}
                    }
                });
});
user2809176
  • 1,042
  • 12
  • 29
  • Ty good sir. My only recommendation is to change the "Bearer" for JwtBearerDefaults.AuthenticationScheme, which is the same, but fancier. – Ramiro G.M. Dec 18 '22 at 01:01
  • Could you clarify why it is better? In my solution there is no JwtBearerDefaults, so in that case i need to install some package. Does it worth it? – user2809176 Dec 19 '22 at 09:11
  • 1
    Using the JwtBearerDefaults is not "better" in any way friend...I just find its more elegant. Besides, using defined constants prevents typo errors...For me its a good practice. – Ramiro G.M. Dec 19 '22 at 16:27
  • yes, it is better to avoid magic strings, agree) – user2809176 Dec 19 '22 at 18:39
  • 1
    thanks, work well for me and if someone have problem with that you should pass header of Authorization that should look like "bearer [accessTokenValue]", for example in react: config.headers['Authorization'] = `Bearer ${auth?.accessToken}`; – Daniel Ezra Mar 14 '23 at 11:53
7

There is no need to generate token separate and key in swagger. Swagger support generation part too. Below work for me with asp.net core 3.1 and keycloack auth.

swagger.AddSecurityDefinition(JwtBearerDefaults.AuthenticationScheme, new OpenApiSecurityScheme
{
    Type = SecuritySchemeType.OAuth2,
    Flows = new OpenApiOAuthFlows
    {
        Implicit = new OpenApiOAuthFlow
        {
            AuthorizationUrl = new Uri("https://youauthsrv.com/auth/realms/your-realm/protocol/openid-connect/auth"),
        }
    },
    In = ParameterLocation.Header,
    Scheme = JwtBearerDefaults.AuthenticationScheme,
});

swagger.AddSecurityRequirement(new OpenApiSecurityRequirement
{
    {
        new OpenApiSecurityScheme
        {
            Reference = new OpenApiReference
            {
                Type = ReferenceType.SecurityScheme,
                Id = JwtBearerDefaults.AuthenticationScheme
            }
        },
        new string[] {}
    }
});

in Configure

app.UseSwaggerUI(c =>
{
    c.OAuthClientId("clientname");
    c.OAuthRealm("your-realm");
});
cdev
  • 5,043
  • 2
  • 33
  • 32
4

Currently Swagger has functionality for authentication with JWT-token and can automatically add token into header, I have answered here.

Pavel K.
  • 983
  • 9
  • 21