How to send an HTTP 4xx-5xx response with CORS headers in an ASPNET.Core web app?

前端 未结 1 1674
一向
一向 2021-01-13 03:42

I have a standard ASP.NET Core 2 Web App acting as a REST/WebApi. For one of my endpoints I return an HTTP 400 when the user provides bad search/filter querystr

1条回答
  •  孤城傲影
    2021-01-13 04:24

    In the ExceptionHandler middleware, the Response is cleared before being passed into your own middleware function, as can be seen in the source:

    try
    {
        await _next(context);
    }
    catch (Exception ex)
    {
        // ...
        context.Response.Clear();
    
        // ...
        await _options.ExceptionHandler(context);
    
        // ..
    }
    

    Of course, this means that any response headers that might have been set in respect to CORS are also being cleared.

    The following code plugs in to the general CORS system, and I believe does appear to mostly satisfy your requirement that the configuration from ConfigureServices can be used:

    var corsService = httpContext.RequestServices.GetService();
    var corsPolicyProvider = httpContext.RequestServices.GetService();
    var corsPolicy = await corsPolicyProvider.GetPolicyAsync(httpContext, null);
    
    corsService.ApplyResult(
        corsService.EvaluatePolicy(httpContext, corsPolicy),
        httpContext.Response);
    

    GetPolicyAsync takes the name of a policy as the second parameter - If this is null (as in my example), it will use the default policy, if this has been set up.

    I've not included null-checks or anything in the code example, in order to keep it focussed, but this approach is working in a test project I have built.

    This approach is heavily influenced by the CorsAuthorizationFilter source code in Microsoft.AspNetCore.Mvc.Cors.

    EDIT: You're not using a named policy in your example code, but you can switch over to one using the following:

    .AddCors(corsOptions => corsOptions.AddPolicy(
        "Default",
        corsPolicyBuilder => corsPolicyBuilder
            .AllowAnyOrigin()
            .AllowAnyHeader()
            .AllowAnyMethod()));
    

    This uses AddPolicy - I mentioned AddDefaultPolicy in the comments, but it looks like this is not in the current release and so not available yet. With the changes above, you can just call UseCors like so:

    app.UseCors("Default");
    

    The final change is to update to the following in your exception handling code:

    await corsPolicyProvider.GetPolicyAsync(httpContext, "Default");
    

    You'd be better off using some sort of const string for this, especially as it's likely all running from the same file. The main change here is no longer attempting to use the default named policy, as I was looking at the current version of the source code on GitHub that is yet to be released.

    0 讨论(0)
提交回复
热议问题