简体   繁体   中英

Publish web site with CORS enabled

I'm diving into the deployment of websites for the first time. I'm making Cross Origin Request (CORS) in the web api controller from an Angular controller on the client. For development, I've set the EnableCors attribute on the Web Api controller, but obviously, that's pointing to a site on my local machine. I'm trying to figure out how to easily transform that setting as I move it to a hosted production site.

Enable CORS For All Domains

You first option is to enable CORS for all domains. This might not be the most secure option if, for example, you know that your API will be accessed only from a pre-defined set of web sites (eg your Angular app). But it some cases it is OK to enable CORS globally.

You can do it from WebApiConfig :

public static class WebApiConfig
{
    public static void Register(HttpConfiguration config)
    {
        // Enable CORS globally for all routes
        var enableCorsAttribute = new EnableCorsAttribute("*", "*", "*");
        config.EnableCors(enableCorsAttribute);

        // Other configurations
    }
}

Or enable CORS support in config and then use EnableCors attribute on specific controllers/actions:

public static class WebApiConfig
{
    public static void Register(HttpConfiguration config)
    {
        config.EnableCors();

        // Other configurations
    }
}

public class ValuesController : ApiController
{    
    [HttpGet]
    [Route("api/values")]
    [EnableCors(origins: "http://www.example.com", headers: "*", methods: "*")]
    public string[] GetValue()
    {

    }
}

Enable CORS From Azure Portal

If host in Azure, I think Web Apps now allow you to enable CORS support and to specify allowed domains right from the Azure Portal:

在此处输入图片说明

Enable CORS Based on App Settings

Another option is to enable CORS for domains that can be configured from App Settings. This way you can change allowed domains for different API instances using web.config transforms, deployment token injection, or just Azure App Settings. This can be easily achieved by creating your own attribute that implements ICorsPolicyProvider interface:

// The implementation below supports only a single origin and
// doesn't allow you to specify allowed headers or request types.
// But it can be easily extended to support these scenarios as well.
public class EnableCorsWithConfigAttribute : Attribute, ICorsPolicyProvider
{
    private readonly string configKey;

    public EnableCorsWithConfigAttribute(string configKey)
    {
        this.configKey = configKey;
    }

    public Task<CorsPolicy> GetCorsPolicyAsync(HttpRequestMessage request, 
                                               CancellationToken cancellationToken)
    {
        var policy = new CorsPolicy
        {
            AllowAnyOrigin = false,
            AllowAnyHeader = true,
            AllowAnyMethod = true,
        };

        if (ConfigurationManager.AppSettings
                                .AllKeys
                                .Contains(configKey))
        {
            var origin = ConfigurationManager.AppSettings[configKey];
            if (!origins.IsNullOrWhitespace())
            {
                policy.AllowAnyOrigin = origins.Equals("*");
                if (!policy.AllowAnyOrigin) policy.Origins.Add(origin);
            }
        }

        return Task.FromResult(policy);
    }
}

Then you can use it as follows:

public class ValuesController : ApiController
{    
    [HttpGet]
    [Route("api/values")]
    [EnableCorsWithConfig("Application:Cors:AllowedOrigin")]
    public string[] GetValue()
    {

    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM