Problem in accessing custom header in SwaggerUI while migrating from .NET Core 2.1 to .NET Core 3.1

629 Views Asked by At

I have a custom authorization filter created in my .NET Core App that I use to authorize requests. This header in my .NET Core 2.1 used to look like this:

public class AddUnionAuthorizationHeader : IOperationFilter
{
    public void Apply(Operation operation, OperationFilterContext context)
    {
        if (operation == null) return;

        if (operation.Parameters == null)
        {
            operation.Parameters = new List<IParameter>();
        }

        var authorizeAttributes = context.ApiDescription
                                            .ControllerAttributes()
                                            .Union(context.ApiDescription.ActionAttributes())
                                            .OfType<AuthorizeAttribute>();

        if (!authorizeAttributes.Any())
            return;

        var parameter = new NonBodyParameter
        {
            Name = "Authorization",
            In = "header",
            Description = "The authorization token for a logged-in member.",
            Required = true,
            Type = "string"
        };
        operation.Parameters.Add(parameter);
    }
}

And I could access the token like this:

public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)
{

   string authorizationBlob = context.HttpContext.Request.Headers["Authorization"];
   var authorizedMember = await authorizer.Check(authorizationBlob);

   //So on
}

Now I ported my app to .NET Core 3.1, so I used the following:

public void Apply(OpenApiOperation operation, OperationFilterContext context)
{
    if (operation == null) return;

    if (operation.Parameters == null)
    {
        operation.Parameters = new List<OpenApiParameter>();
    }

    var authorizeAttributes = context.MethodInfo.DeclaringType.GetCustomAttributes(true)
                                .Union(context.MethodInfo.GetCustomAttributes(true))
                                .OfType<AuthorizeAttribute>();


    if (!authorizeAttributes.Any())
        return;

    var parameter = new OpenApiParameter
    {
        Name = "Authorization",
        In = ParameterLocation.Header,
        Description = "The authorization token for a logged-in member.",
        Required = true,
        Schema = new OpenApiSchema { Type = "string" }
    };

    operation.Parameters.Add(parameter);
}

Now when I try to get the value of the token like this:

public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)
{   
    StringValues authorizationToken;
    //string authorizationBlob = context.HttpContext.Request.Headers["Authorization"];
    context.HttpContext.Request.Headers.TryGetValue("Authorization", out authorizationToken);
    string authorizationBlob = authorizationToken;
    var authorizedMember = await authorizer.Check(authorizationBlob);
}

The header is always coming empty.

The interesting part is when I change the OpenApiParameter definition to this:

var parameter = new OpenApiParameter
{
    Name = "X-Authorization",
    In = ParameterLocation.Header,
    Description = "The authorization token for a logged-in member.",
    Required = true,
    Schema = new OpenApiSchema { Type = "string" }
};

Then I am able to access the token like this:

context.HttpContext.Request.Headers.TryGetValue("X-Authorization", out authorizationToken);
string authorizationBlob = authorizationToken;

So my question is that why I am not able to retrieve the token when I use the Name = "Authorization" when I create my OpenApiParameter ?

The problem is that if I change the name to Name = "X-Authorization", then I need to change it in the client app for all cases which will be cumbersome.

Any workaround on the above case?

1

There are 1 best solutions below

2
On BEST ANSWER

I used this 2 packages:

<PackageReference Include="Microsoft.OpenApi" Version="1.3.1" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="5.0.0" />

I reproduced your issue, and I also think this is weird why Authorization won't work but X-Authorization or Authorizations can work, until I check the details of the OpenApiParameter...

If in is "header" and the name field is "Accept", "Content-Type" or "Authorization", the parameter definition SHALL be ignored.

enter image description here