Currently having an issue with authorization headers in swashbuckle for .net core
The first line of code on every endpoint is:
string auth = Request.Headers["Authorization"];
When using postman, everything works smoothly, but when making a request from localhost/swagger, the header is empty
when a breakpoint is inserted, the header is a null value.
the body of the request is in tact and everything works properly when the authorization is removed from the endpoint
In my services.AddSwaggerGen I add the security definition:
services.AddSwaggerGen(c =>
{
c.SwaggerDoc("v1", new Info
{
Version = "v1",
Title = "Employee Navigator",
Description = "Authorization Key: Z29vZEtleQ==",
});
c.AddSecurityDefinition("Bearer", new ApiKeyScheme
{
Name = "Authorization",
In = "header",
Type = "apiKey",
Description = "Authorization Key: Z29vZEtleQ=="
});
});
I have updated each of the following to be sure I wasn't missing anything:
Swashbuckle.AspNetCore.Swagger
Swashbuckle.AspNetCore.SwaggerGen
Swashbuckle.AspNetCore.SwaggerUI
my csproj file contains:
`
<PackageReference Include="Swashbuckle.AspNetCore.Swagger" Version="2.4.0" />
<PackageReference Include="Swashbuckle.AspNetCore.SwaggerGen" Version="2.4.0" />
<PackageReference Include="Swashbuckle.AspNetCore.SwaggerUi" Version="2.4.0" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="1.1.0" />`
You have to add a "securityrequirement", not just the definition.
On Wed, Apr 18, 2018 at 2:17 PM, Patrick Reese notifications@github.com
wrote:
Currently having an issue with authorization headers in swashbuckle for
.net core
The first line of code on every endpoint is:string auth = Request.Headers["Authorization"];
When using postman, everything works smoothly, but when making a request
from localhost/swagger, the header is empty
when a breakpoint is inserted, the header is a null value.
the body of the request is in tact and everything works properly when the
authorization is removed from the endpointIn my services.AddSwaggerGen I add the security definition:
services.AddSwaggerGen(c => { c.SwaggerDoc("v1", new Info { Version = "v1", Title = "Employee Navigator", Description = "Authorization Key: Z29vZEtleQ==", }); c.AddSecurityDefinition("Bearer", new ApiKeyScheme { Name = "Authorization", In = "header", Type = "apiKey", Description = "Authorization Key: Z29vZEtleQ==" }); });I have updated each of the following to be sure I wasn't missing anything:
Swashbuckle.AspNetCore.Swagger
Swashbuckle.AspNetCore.SwaggerGen
Swashbuckle.AspNetCore.SwaggerUImy csproj file contains:
`
` —
You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub
https://github.com/domaindrivendev/Swashbuckle.AspNetCore/issues/696,
or mute the thread
https://github.com/notifications/unsubscribe-auth/AFIxOutAaOckPlqSjFXjtRIPI3aCJO4tks5tp593gaJpZM4TatTG
.
I thought that was my issue, so I added:
c.AddSecurityRequirement(new Dictionary<string, IEnumerable<string>>
{
{ "Authorization", new[] { "readAccess", "writeAccess" } }
});
but nothing changed
@preese13 - try it with an empty array ...
c.AddSecurityRequirement(new Dictionary<string, IEnumerable<string>> { { "Authorization", new[] { } } });
From the Swagger 2.0 Spec
Each name must correspond to a security scheme which is declared in the Security Definitions. If the security scheme is of type "oauth2", then the value is a list of scope names required for the execution. For other security scheme types, the array MUST be empty.
I had tried creating it with an empty array but I got the error message:
The best overloaded Add method 'Dictionary
>.Add(string, IEnumerable )' for the collection initializer has some invalid arguments
which makes little to no sense (at least to me) I thought that the invalid argument might have been "Authorization" so I switched it out with "apikey" and "api_key" as I saw the latter example given in the swaggerdoc documentation here:
https://swagger.io/specification/#securityRequirementObject
being unable to initialize an empty array at all, I figured it was time to create an issue
Just a syntax error - the array type can’t be inferred if it’s empty. Try “new string[] {}”
Nope, after implementing the new syntax I recieved:
Exception has occurred: CLR/System.NullReferenceException
An exception of type 'System.NullReferenceException' occurred in mockAPI.dll but was not handled in user code: 'Object reference not set to an instance of an object.'
I think I probably should have pointed out that I recently updated all of the swashbuckle packages for the first time since december. everything had been working fine before that. I updated the packages upon revisiting the project. Previously I had not used a security requirement at all, but it was working fine. I have been messing around with adding a document filter to my startup.cs file
(sorry for not using the code-formater its being difficult)
public class SecurityRequirementsDocumentFilter : IDocumentFilter
{
public void Apply(SwaggerDocument document, DocumentFilterContext context)
{
document.Security = new List
{
new Dictionary
{
{ "Bearer", new string[]{ } },
{ "Basic", new string[]{ } },
}
};
}
}
I was still having the same issue, but then I changed my security requirement from "Authorization" to "Bearer"
c.AddSecurityRequirement(new Dictionary<string, IEnumerable<string>>
{
{ "Bearer", new string[] { } }
});
and it works fine
FYI, there is no need to add a SecurityRequirementsDocumentFilter.
define the add security requirement as
c.AddSecurityRequirement(new Dictionary<string, IEnumerable<string>>
inside of which you will define:
{ "Bearer", new string[] { } }
the security definition should be defined as
c.AddSecurityDefinition("Bearer", new ApiKeyScheme
inside of which I have:
Name = "Authorization",
In = "header",
Type = "apiKey",
Description = ""
Correct - you would only need to use the operation filter if you need to specify per-operation security requirements. If the scheme is applied globally, your suggestion is much more convenient
@preese13 could you please provide full code. I'm having same issue
@ngohungphuc
Hey sorry I took so long to get back to you, I haven't checked github in a few days.. If you still need it here is what I think you want
c.AddSecurityDefinition("Bearer", new ApiKeyScheme
{
Name = "Authorization",
In = "header",
Type = "apiKey",
});
c.AddSecurityRequirement(new Dictionary<string, IEnumerable<string>>
{
{ "Bearer", new string[] { } }
});
Please explain how to do this in ASP.NET Core 2.2. I have the following code in my startup but the "Available operations" popup is still empty and I do not get the "Authorization" added to the request headers.
// Add security definitions
var securityScheme = new OpenApiSecurityScheme()
{
Description = "Please enter into field the word 'Bearer' followed by a space and the JWT value",
Name = "Authorization",
In = ParameterLocation.Header,
Type = SecuritySchemeType.Http,
BearerFormat = "JWT",
Scheme = "bearer"
};
c.AddSecurityDefinition("Bearer", securityScheme);
// Add security requirements globally. If needs to be unique per operation then use IOperationFilter.
var securityRequirement = new OpenApiSecurityRequirement();
securityRequirement.Add(securityScheme, new string[] { });
c.AddSecurityRequirement(securityRequirement);
I'm also getting the same issue as @teamboyd. The curl statement does not have the relevant -H parameters. Please help.
Please explain how to do this in ASP.NET Core 2.2. I have the following code in my startup but the "Available operations" popup is still empty and I do not get the "Authorization" added to the request headers.
// Add security definitions var securityScheme = new OpenApiSecurityScheme() { Description = "Please enter into field the word 'Bearer' followed by a space and the JWT value", Name = "Authorization", In = ParameterLocation.Header, Type = SecuritySchemeType.Http, BearerFormat = "JWT", Scheme = "bearer" }; c.AddSecurityDefinition("Bearer", securityScheme); // Add security requirements globally. If needs to be unique per operation then use IOperationFilter. var securityRequirement = new OpenApiSecurityRequirement(); securityRequirement.Add(securityScheme, new string[] { }); c.AddSecurityRequirement(securityRequirement);
I have found the solution here:
https://github.com/domaindrivendev/Swashbuckle.AspNetCore/blob/master/test/WebSites/OAuth2Integration/Startup.cs
c.AddSecurityRequirement( new OpenApiSecurityRequirement {
{
new OpenApiSecurityScheme {
Reference = new OpenApiReference { Type = ReferenceType.SecurityScheme, Id = "Bearer" }
},
new string[] { }
}
} );
It works @magiak tks very much.
Please explain how to do this in ASP.NET Core 2.2. I have the following code in my startup but the "Available operations" popup is still empty and I do not get the "Authorization" added to the request headers.
// Add security definitions var securityScheme = new OpenApiSecurityScheme() { Description = "Please enter into field the word 'Bearer' followed by a space and the JWT value", Name = "Authorization", In = ParameterLocation.Header, Type = SecuritySchemeType.Http, BearerFormat = "JWT", Scheme = "bearer" }; c.AddSecurityDefinition("Bearer", securityScheme); // Add security requirements globally. If needs to be unique per operation then use IOperationFilter. var securityRequirement = new OpenApiSecurityRequirement(); securityRequirement.Add(securityScheme, new string[] { }); c.AddSecurityRequirement(securityRequirement);I have found the solution here:
https://github.com/domaindrivendev/Swashbuckle.AspNetCore/blob/master/test/WebSites/OAuth2Integration/Startup.cs
c.AddSecurityRequirement( new OpenApiSecurityRequirement { { new OpenApiSecurityScheme { Reference = new OpenApiReference { Type = ReferenceType.SecurityScheme, Id = "Bearer" } }, new string[] { } } } );
This should be documented.
Adding Reference = new OpenApiReference {... property solved my problem:
services.AddSwaggerGen(c => {
var securityScheme = new OpenApiSecurityScheme {
Reference = new OpenApiReference {
Type = ReferenceType.SecurityScheme,
Id = "Bearer"
},
Description = "JWT Token gerekiyor!",
In = ParameterLocation.Header, // Header içinde Bearer token key gelecek
Name = "Authorization", // Header içindeki token'ın header key bilgisi> Authorization: Bearer xlaskdfjsdf...
Type = SecuritySchemeType.ApiKey,
Scheme = "Bearer"
};
c.AddSecurityDefinition("Bearer", securityScheme);
// Security Requirement
c.AddSecurityRequirement(new OpenApiSecurityRequirement() {
{ securityScheme, Array.Empty<string>() }
});
});

Whole ConfigureServices and Configure methods:
public void ConfigureServices(IServiceCollection services) {
services.AddControllers();
#region Api Versiyonlama
services.AddApiVersioning(v => {
v.ReportApiVersions = true;
v.AssumeDefaultVersionWhenUnspecified = true;
v.DefaultApiVersion = new ApiVersion(1, 0);
/* Eğer versiyon bilgisi tarih olsun istersek: */
//v.DefaultApiVersion = new ApiVersion(new DateTime(2016, 7, 1));
/* Eğer header ile versiyon bilgisi göndermezsek
* - ya URL Segment
* - ya da Querystring
* olarak versiyon bilgisini geçirebileceğiz.
*
* Eğer versiyon bilgisini HTTP Header içinde göndermek istersek
* URL Segment içinde versiyon bilgisi alabilecek şekilde işaretlenmemiş
* denetleyiciler yani Querystring ile çalışabilen denetleyiciler
* header'dan gelen versiyon bilgisine göre çalışabilir.
* Çalışır > [Route("api/versioning")]
* ÇalışMAZ > [Route("api/v{version:apiVersion}/versioning")]
*
* Header içinde versiyonu taşıyan key'in ne olacağını burada belirtebiliriz
*/
v.ApiVersionReader = new HeaderApiVersionReader("verMEZsion");
});
#endregion
#region Swagger 2.0 - OpenApi 3.0
services.AddSwaggerGen(c => {
/* new SwaggerDocument()
* Tüm Controller sınıflarının versiyon bilgilerini topla
* ve her biri için SwaggerDocument yarat. Böylece açılır kutuda
* her versiyon için detay bilgi toplayabil.
*/
#region SwaggerDocument Nesnelerini Yarat
foreach (var version in Versions) {
var swaggerDocument = new OpenApiInfo {
Version = version,
Title = "API Şablonu",
Description = "Örnek Web API swagger açıklaması",
TermsOfService = new Uri("https://example.com/terms"),
Contact = new OpenApiContact {
Name = "Shayne Boyer",
Email = string.Empty,
Url = new Uri("https://twitter.com/spboyer"),
},
License = new OpenApiLicense {
Name = "Use under LICX",
Url = new Uri("https://example.com/license"),
}
};
c.SwaggerDoc(version, swaggerDocument);
}
#endregion
/* SwaggerDocument <> Controller Eşleşmesi
* Versiyon numaralarına göre oluşturulmuş SwaggerDocument nesnelerine
* uygun düşecek Controller sınıflarını ekle. Bunun için:
* denetleyicilerin ApiVersionAttribute niteliklerine bak,
* eğer Controller'ın versiyon numarasıyla, SwaggerDocument nesnesinin versiyon numarası aynıysa
* ilgili SwaggerDocument içinde görüntülemek için dahil et.
*/
#region SwaggerDocument nesneleriyle Controller tiplerini eşleştir.
c.DocInclusionPredicate((docName, apiDesc) => {
if (!apiDesc.TryGetMethodInfo(out MethodInfo methodInfo)) return false;
var versions = methodInfo.DeclaringType // Api içinde tanımlı tipleri getir
.GetCustomAttributes(true) // Niteliklerini çek
.OfType<ApiVersionAttribute>() // ApiVersionAttribute tipindeki nitelikleri süz
.SelectMany(attr => attr.Versions); // ApiVersion niteliğindeki Versions özelliklerini flat dön
return versions.Any(v => v.ToString() == docName);
});
#endregion
// Set the comments path for the Swagger JSON and UI.
var xmlFile = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml";
var xmlPath = Path.Combine(AppContext.BaseDirectory, xmlFile);
c.IncludeXmlComments(xmlPath);
});
#endregion
#region Swagger için JSON Web Token Ayarları
services.AddSwaggerGen(c => {
var securityScheme = new OpenApiSecurityScheme {
Reference = new OpenApiReference {
Type = ReferenceType.SecurityScheme,
Id = "Bearer"
},
Description = "JWT Token gerekiyor!",
In = ParameterLocation.Header, // Header içinde Bearer token key gelecek
Name = "Authorization", // Header içindeki token'ın header key bilgisi> Authorization: Bearer xlaskdfjsdf...
Type = SecuritySchemeType.ApiKey,
Scheme = "Bearer"
};
c.AddSecurityDefinition("Bearer", securityScheme);
// Security Requirement
c.AddSecurityRequirement(new OpenApiSecurityRequirement() {
{ securityScheme, Array.Empty<string>() }
});
});
#endregion
#region JSON Web Token ayarları
var jwtSettings = new TokenSettings();
this.Configuration.Bind("jwtSettings", jwtSettings);
services.AddAuthentication(opt => {
/**
* Bir Controller niteliğinde [Authorize] kullandığınızda,
* ilk yetkilendirme sistemine varsayılan olarak bağlaması için
*/
opt.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
/**
* Eğer `services.AddIdentity>()` ile bir kimlik kullanıyorsanız,
* DefaultChallengeScheme sizi bir giriş sayfasına yönlendirmeye çalışacaktır,
* eğer bir kimlik mevcut değilse, 404 döner. Eğer var ve yetkisiz ise 401 "yetkisiz erişim" hatası alacaksınız.
*/
opt.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
}).AddJwtBearer(opt => {
Microsoft.IdentityModel.Tokens.TokenValidationParameters param;
param = new TokenValidationParameters {
// Require Bilgileri yoksa geçersiz kıl!
RequireSignedTokens = true,
RequireExpirationTime = true,
// Neleri doğrulamasını istiyorsak
ValidateIssuer = true,
ValidateAudience = true,
ValidateIssuerSigningKey = true,
ValidateLifetime = true,
// Beklediğimiz Issuer ve Audience bilgilerini veririz
ValidIssuer = jwtSettings.Issuer,
ValidAudience = jwtSettings.Audience,
/**
* Gelen token bilgisiyle, gönderdiğimizin imzası aynı mı diye
* geleni imzalayacak ve kontrol edeceğiz
*/
IssuerSigningKey = jwtSettings.IssuerSigningKey,
};
opt.RequireHttpsMetadata = false; // Production ortamı ise true yani https olsun diyebiliriz
opt.SaveToken = true;
opt.TokenValidationParameters = param;
opt.Events = new JwtBearerEvents() {
OnAuthenticationFailed = context => {
context.Response.StatusCode = 401;
context.Response.ContentType = "application/json; charset=utf-8";
var message = context.Exception.ToString();
var result = JsonConvert.SerializeObject(new { message });
Console.WriteLine("HATA >>>> " + message);
return context.Response.WriteAsync(result);
}
};
});
#endregion
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env) {
if (env.IsDevelopment()) {
app.UseDeveloperExceptionPage();
} else {
app.UseExceptionHandler("/Error/Exception");
app.UseStatusCodePagesWithReExecute("/Error/{0}");
app.UseHsts();
app.UseHttpsRedirection();
}
#region Swagger
// Enable middleware to serve generated Swagger as a JSON endpoint.
app.UseSwagger();
// Enable middleware to serve swagger-ui (HTML, JS, CSS, etc.),
// specifying the Swagger JSON endpoint.
app.UseSwaggerUI(c => {
foreach (var v in Versions) {
// Her versiyon için bir uç nokta yaratmasını Swagger'a söylüyoruz
c.SwaggerEndpoint($"/swagger/{v}/swagger.json", $"API Şablonu v{v}");
}
});
#endregion
#region CORS - Cross Origin Resource Sharing Ayarları
/* AllowAnyOrigin: Herhangi bir domain adından
* AllowAnyMethod: Herhangi bir HTTP metoduyla (GET, POST, PATH vs)
* AllowAnyHeader: Herhangi bir HTTP Header bilgisiyle
* Yani herkesle her durumda her şeyi paylaş
*/
app.UseCors(confPolicy => {
confPolicy.AllowAnyOrigin()
.AllowAnyMethod()
.AllowAnyHeader();
});
#endregion
app.UseRouting();
#region JSON Web Token
/* app.UseAuthorization() metodu app.UseRouting() ile app.UseEndpoints() arasında olmalı!
*
* Configure your application startup by adding app.UseAuthorization()
* inside the call to Configure(..) in the application startup code.
* The call to app.UseAuthorization() must appear between app.UseRouting() and app.UseEndpoints(...)
*/
app.UseAuthentication();
app.UseAuthorization();
#endregion
app.UseEndpoints(endpoints => {
endpoints.MapControllers();
});
}
For anyone looking for .NET Core 3.0 version... here's the code:
@magiak
Por favor, explique como fazer isso no ASP.NET Core 2.2. Eu tenho o seguinte código na minha inicialização, mas o pop-up "Operações disponíveis" ainda está vazio e não recebo a "Autorização" adicionada aos cabeçalhos da solicitação.
// Add security definitions var securityScheme = new OpenApiSecurityScheme() { Description = "Please enter into field the word 'Bearer' followed by a space and the JWT value", Name = "Authorization", In = ParameterLocation.Header, Type = SecuritySchemeType.Http, BearerFormat = "JWT", Scheme = "bearer" }; c.AddSecurityDefinition("Bearer", securityScheme); // Add security requirements globally. If needs to be unique per operation then use IOperationFilter. var securityRequirement = new OpenApiSecurityRequirement(); securityRequirement.Add(securityScheme, new string[] { }); c.AddSecurityRequirement(securityRequirement);Encontrei a solução aqui:
https://github.com/domaindrivendev/Swashbuckle.AspNetCore/blob/master/test/WebSites/OAuth2Integration/Startup.cs
c.AddSecurityRequirement( new OpenApiSecurityRequirement { { new OpenApiSecurityScheme { Reference = new OpenApiReference { Type = ReferenceType.SecurityScheme, Id = "Bearer" } }, new string[] { } } } );
it worked for me, thank you very much
Not sure why mine doesn't work..
// Define the Api Key scheme that's in use (i.e. Implicit Flow)
config.AddSecurityDefinition(ApiKeyAuthenticationOptions.DefaultScheme, new OpenApiSecurityScheme
{
Description = "custom authorization header using the Api Key scheme. Example: \"{token}\"",
In = ParameterLocation.Header,
Name = ApiKeyAuthenticationOptions.HeaderKey,
Type = SecuritySchemeType.ApiKey,
Flows = new OpenApiOAuthFlows
{
Implicit = new OpenApiOAuthFlow
{
AuthorizationUrl = new Uri("/api/connect/validate", UriKind.Relative),
Scopes = new Dictionary<string, string>
{
{ "readAccess", "Access read operations" },
{ "writeAccess", "Access write operations" }
}
}
}
});
config.AddSecurityRequirement(new OpenApiSecurityRequirement
{
{
new OpenApiSecurityScheme
{
Reference = new OpenApiReference
{
Type = ReferenceType.SecurityScheme,
Id = ApiKeyAuthenticationOptions.DefaultScheme
}
},
new[] { "readAccess", "writeAccess" }
}
});
// add Security information to each operation for OAuth2
config.OperationFilter<SecurityRequirementsOperationFilter>();
And this class in case required:
public class ApiKeyAuthenticationOptions : AuthenticationSchemeOptions
{
public const string DefaultScheme = "API Key";
public string Scheme => DefaultScheme;
public string AuthenticationType = DefaultScheme;
public const string HeaderKey = "X-Api-Key";
}
I met the same issue before and resolved it.
Now the available Authorization header works fine.
Please check my latest sample using SwashBuckle v5.5.1 and netcore 3.1
https://github.com/capcom923/MySwashBuckleSwaggerWithJwtToken

Most helpful comment
I have found the solution here:
https://github.com/domaindrivendev/Swashbuckle.AspNetCore/blob/master/test/WebSites/OAuth2Integration/Startup.cs
c.AddSecurityRequirement( new OpenApiSecurityRequirement { { new OpenApiSecurityScheme { Reference = new OpenApiReference { Type = ReferenceType.SecurityScheme, Id = "Bearer" } }, new string[] { } } } );