从 .NET Core 2.1 迁移到 .NET Core 3.1 时在 SwaggerUI 中访问自定义 header 时出现问题

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

我在我的 .NET Core 应用程序中创建了一个自定义授权过滤器,用于授权请求。这个 header 在我的 .NET Core 2.1 中曾经是这样的:

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

我可以这样访问令牌:

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

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

   //So on
}

现在我将我的应用程序移植到 .NET Core 3.1,所以我使用了以下内容:

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

现在,当我尝试像这样获取令牌的值时:

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

header 总是空的。

有趣的部分是当我将 OpenApiParameter 定义更改为:

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

然后我可以像这样访问令牌:

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

所以我的问题是为什么我在创建 OpenApiParameter 时使用 Name = "Authorization" 时无法检索令牌?

问题是,如果我将名称更改为 Name = "X-Authorization",那么我需要在客户端应用程序中为所有情况更改它,这将很麻烦。

上述情况有什么解决方法吗?

我使用了这 2 个包:

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

我重现了你的问题,我也认为这很奇怪,为什么 Authorization 不起作用,但 X-AuthorizationAuthorizations 可以,直到我检查 OpenApiParameter...

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