WebAPI - Enable CORS for Subdomains

左心房为你撑大大i 提交于 2021-02-08 15:01:28

问题


I would like to be enable CORS for a web-api application with the following criteria:

  1. Allow HTTPS or HTTP for the same site
  2. Ignore the SUBDOMAIN - Meaning mysite.com and www.mysite.com are same

I would like to do this for multiple sites in an elegant way, rather than putting all the permutations as comma delimited.

Thanks in advance!


回答1:


Here you go.

Adding Git gist if it requires any revisions or bug fixes.

public class WildcardOriginCorsPolicy : Attribute, ICorsPolicyProvider
    {
        private readonly string _origins;
        private readonly string _headers;
        private readonly string _methods;

        //private readonly CorsPolicy _policy;
        //
        // Summary:
        //     Initializes a new instance of the WildcardOriginCorsPolicy class.
        //
        // Parameters:
        //   origins:
        //     Comma-separated list of origins that are allowed to access the resource. Use
        //     "*" to allow all.
        //     "*.example.com" for subdomains
        //
        //   headers:
        //     Comma-separated list of headers that are supported by the resource. Use "*" to
        //     allow all. Use null or empty string to allow none.
        //
        //   methods:
        //     Comma-separated list of methods that are supported by the resource. Use "*" to
        //     allow all. Use null or empty string to allow none.
        public WildcardOriginCorsPolicy(string origins, string headers, string methods)
        {
            this._origins = origins;
            this._headers = headers;
            this._methods = methods;
        }

        public bool SupportsCredentials { get; set; }

        public Task<CorsPolicy> GetCorsPolicyAsync(HttpRequestMessage request, CancellationToken cancellationToken)
        {
            var policy = CreatePolicy(request.GetCorsRequestContext(), this._origins, this._headers, this._methods);
            policy.SupportsCredentials = this.SupportsCredentials;

            return Task.FromResult(policy);
        }

        private static CorsPolicy CreatePolicy(CorsRequestContext requestContext, string origins, string headers, string methods)
        {

            var corsPolicy = new CorsPolicy();
            if (origins == "*")
            {
                corsPolicy.AllowAnyOrigin = true;
            }
            else
            {
                var originsStringArray = origins.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
                var requestOrigin = requestContext.Origin.ToLowerInvariant();

                foreach (var originItem in originsStringArray)
                {
                    ////Check if the current request uri matches with any of the wildcard origins.
                    if (Regex.IsMatch(requestOrigin, WildCardToRegularExpression(originItem)))
                    {
                        corsPolicy.Origins.Add(requestOrigin);
                    }
                }
            }

            if (!String.IsNullOrEmpty(headers))
            {
                if (headers == "*")
                {
                    corsPolicy.AllowAnyHeader = true;
                }
                else
                {
                    var headersStringArray = headers.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
                    corsPolicy.Headers.AddAll(headersStringArray);
                }
            }

            if (!String.IsNullOrEmpty(methods))
            {
                if (methods == "*")
                {
                    corsPolicy.AllowAnyMethod = true;
                }
                else
                {
                    var methodsStringArray = methods.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
                    corsPolicy.Methods.AddAll(methodsStringArray);
                }
            }

            return corsPolicy;
        }

        private static string WildCardToRegularExpression(String value)
        {
            return "^" + Regex.Escape(value).Replace("\\?", ".").Replace("\\*", ".*") + "$";
        }
    }

Use it like this.

var cors = new WildcardOriginCorsPolicy("*.example.com,http://localhost:*", "*", "POST,PUT,DELETE,GET,OPTIONS") { SupportsCredentials = true };
config.EnableCors(cors);



回答2:


The only way i can think of doing this besides explicitly specifying all the permutations is by implementing a custom CORS policy.

You can read more about it here.




回答3:


you can implement this dynamic for *.mydomain.com without the wildcard. You can refer the following method (Custom CORS Policy Providers)

public class MyCorsPolicy : Attribute, ICorsPolicyProvider
    {
        public Task<CorsPolicy> GetCorsPolicyAsync(HttpRequestMessage request, CancellationToken cancellationToken)
        {
            var policy = new CorsPolicy();
            var requestUri = request.RequestUri;
            var authority = requestUri.Authority.ToLowerInvariant();
            if (authority.EndsWith(".mydomain.com") || authority == "mydomain.com")
            {
                // returns a url with scheme, host and port(if different than 80/443) without any path or querystring
                var origin = requestUri.GetComponents(System.UriComponents.SchemeAndServer, System.UriFormat.SafeUnescaped);
                policy.Origins.Add(origin);
            }

            return Task.FromResult(policy);
        }
    }


    [MyCorsPolicy]
    public class TestController : ApiController
    {
    }

As already mentioned in other posts you can visit the url https://msdn.microsoft.com/en-us/magazine/dn532203.aspx for more info regarding Custom CORS Policy Providers



来源:https://stackoverflow.com/questions/36307907/webapi-enable-cors-for-subdomains

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!