0

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=="
            });
            c.AddSecurityRequirement(new Dictionary<string, IEnumerable<string>>
            {
                { "Authorization", new[] { "readAccess", "writeAccess" } }
            });

        });

I have updated each of the following to be sure I wasn't missing anything: my csproj file contains:

  <ItemGroup>
<Folder Include="wwwroot\" />
<PackageReference Include="Microsoft.AspNetCore.StaticFiles" Version="2.0.1" />
<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" />

PWR
  • 29
  • 5

3 Answers3

1

First of all, you can use AddSwaggerGen method like this

  services.AddSwaggerGen(c =>
        {
            c.SwaggerDoc(
                "v1",
                new OpenApiInfo
                {
                    Title = "v1",
                    Description = "My Web - API",
                    Version = "V1.0.0"
                });
            // Add security definitions
            var securityScheme = new OpenApiSecurityScheme()
            {
                Description = "Standard Authorization header using the Bearer scheme. Example: \"bearer {token}\"",
                Name = "Authorization",
                In = ParameterLocation.Header,
                Type = SecuritySchemeType.Http,
                BearerFormat = "JWT",
                Scheme = "bearer"
            };
            c.AddSecurityDefinition("Bearer", securityScheme);
            
            //And Add security requirements globally.  If needs to be unique per operation then use IOperationFilter. 
            c.OperationFilter<AuthResponsesOperationFilter>();
        });

For example AuthResponsesOperationFilter can be removed authorize pad lock icon on AllowAnonymous methods

And AuthResponsesOperationFilter :

public class AuthResponsesOperationFilter : IOperationFilter
{
    public void Apply(OpenApiOperation operation, OperationFilterContext context)
    {
        var authAttributes = context.MethodInfo.DeclaringType.GetCustomAttributes(true)
            .Union(context.MethodInfo.GetCustomAttributes(true))
            .OfType<AuthorizeAttribute>();

        if (authAttributes.Any())
        {
            var securityRequirement = new OpenApiSecurityRequirement()
            {
                {
                    // Put here you own security scheme, this one is an example
                    new OpenApiSecurityScheme
                    {
                        Reference = new OpenApiReference
                        {
                            Type = ReferenceType.SecurityScheme,
                            Id = "Bearer"
                        },
                        Scheme = "Bearer",
                        Name = "Authorization",
                        In = ParameterLocation.Header,
                        Description = "Standard Authorization header using the Bearer scheme. Example: \"bearer {token}\"",
                        Type = SecuritySchemeType.ApiKey,
                        BearerFormat = "JWT"
                    },
                    new List<string>()
                }
            };
            
            operation.Security = new List<OpenApiSecurityRequirement> { securityRequirement };
            operation.Responses.Add("401", new OpenApiResponse { Description = "Unauthorized" });
        }
    }
}
ahmeticat
  • 1,899
  • 1
  • 13
  • 28
0

The problem here is that the name in your security definition ("Bearer") does not match the name added to your security requirement ("Authorization"). For background context, there used to be a bug in SwashBuckle that meant that it enforced authorization without the SecurityRequirement defined so many found that it suddenly stopped working for them. The Requirement definition is a bit clunky and leads to issues like these.

If you change the SecurityRequirement to match the code below it should work:

 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=="
        });
        c.AddSecurityRequirement(new Dictionary<string, IEnumerable<string>>
        {
            { "Bearer", new[] { "readAccess", "writeAccess" } }
        });

    });
Sarel Esterhuizen
  • 1,628
  • 17
  • 18
-1

Found the answer in case anyone has this issue:

My solution can be found here: https://github.com/domaindrivendev/Swashbuckle.AspNetCore/issues/696

more info on the topic can be found here: https://github.com/domaindrivendev/Swashbuckle.AspNetCore/issues/603

PWR
  • 29
  • 5