How to generate Options(CORS) with Swagger

Viewed 6671

For a project we are working on we are generating an Swagger File automatically. However at this moment we are struggling with the CORS part.

We are using the Amazon API gateway import api functionality. To use this in combination with Swagger and CORS, we have to create an additional action (operation) in our source code which allows CORS(options) for each api method (operation)! eg:

    [HttpOptions]
    [Route("{id}")]
    [ProducesResponseType((int)HttpStatusCode.OK)]
    public IActionResult UserOptions()
    {
        return new OkResult();
    }

As you can see this makes the code a lot dirtier. this is a temporary fix, but we can not find another way. Is there any way to generate this in the swagger definition file automatically? Or how can we do this, Amazon API gateway required this (documentation: http://docs.aws.amazon.com/apigateway/latest/developerguide/how-to-cors.html)

4 Answers

I had the same issues and I end up creating a utility in Java which automatically adds these headers to Swagger JSON. You can run it before importing it to API Gateway and import the output JSON which has CORS enabled in all the methods

https://github.com/anandlalvb/SwaggerToAPIGateway

It is tedious task to add these headers to all your methods in Swagger JSON.

            "headers": {
            "Access-Control-Allow-Origin": {
                "type": "string"
            },
            "Access-Control-Allow-Methods": {
                "type": "string"
            },
            "Access-Control-Allow-Headers": {
                "type": "string"
            }
        }

I hope this utility may help you to do that easily

I had the exact same issue, however, in combination with Azure API management. I used asidis' code and modified it to suit my needs.

Obviously, i removed the AWS extension part and i used a newer version of Swashbuckle.AspNetCore package (5.5.1)

public class CorsDocumentFilter : IDocumentFilter
{
    private const string AcaOrigin = "Access-Control-Allow-Origin";
    private const string AcaMethods = "Access-Control-Allow-Methods";
    private const string AcaHeaders = "Access-Control-Allow-Headers";

    private static OpenApiOperation BuildCorsOptionOperation(OpenApiOperation operation)
    {
        var response = new OpenApiResponse
        {
            Description = "Successful operation",
            Headers = new Dictionary<string, OpenApiHeader>
            {
                { AcaOrigin, new OpenApiHeader {Description = "URI that may access the resource" } },
                { AcaMethods, new OpenApiHeader {Description = "Method or methods allowed when accessing the resource" } },
                { AcaHeaders, new OpenApiHeader {Description = "Used in response to a preflight request to indicate which HTTP headers can be used when making the request." } },
            }
        };

        return new OpenApiOperation
        {
            Summary = "CORS Preflight request",

            // Path parameters are required for Azure APIM
            Parameters = operation.Parameters.Where(x => x.In == ParameterLocation.Path).ToList(),
            Tags = new List<OpenApiTag> { new OpenApiTag { Name = "CORS" } },
            Responses = new OpenApiResponses
            {
                { "200", response }
            },
        };
    }
    
    public void Apply(OpenApiDocument swaggerDoc, DocumentFilterContext context)
    {
        foreach (var path in swaggerDoc.Paths)
        {
            var operation = path.Value.Operations.Values.First();
            var corsOptionOperation = BuildCorsOptionOperation(operation);
            path.Value.Operations.Add(OperationType.Options, corsOptionOperation);
        }
    }
}
Related