1

I want to use CORS with multiple sources for my web application but I am stuck now. It worked with the first source because I set the Allow-Origin header from Web.config. But now I want to do it programmatically to change the header based on the Origin/Referer.

  • won't work in browsers like Chrome.

I created the Application_BeginRequest in Global.asax. Problem is...it is only triggered for GET/POST requests but not for the OPTIONS call. Second option to add OnActionExecuting in a global filter. Same problem. OPTIONS requests don't trigger this method.

Any idea what is going around here?

I am using .NET Framework 4.8.

Code:

    public class MyActionFilterAttribute : ActionFilterAttribute
    {
        private readonly string NEEDS_CUSTOM_ORIGIN = ConfigurationManager.ConnectionStrings["CustomOrigin"]?.ConnectionString ?? "";

        public override void OnActionExecuting(ActionExecutingContext filterContext)
        {
            if (filterContext.HttpContext.Request.HttpMethod == "OPTIONS")
            {
                // IT NEVER HITS THIS OR ANY OTHER PART OF THIS METHOD FOR OPTIONS
            }
                if (!string.IsNullOrWhiteSpace(NEEDS_CUSTOM_ORIGIN))
            {
                var originHeader = "";
                if (((IList)filterContext.HttpContext.Request.Headers.AllKeys).Contains("Origin"))
                {
                    originHeader = filterContext.HttpContext.Request.Headers["Origin"];
                }
                else if (((IList)filterContext.HttpContext.Request.Headers.AllKeys).Contains("Referer"))
                {
                    originHeader = filterContext.HttpContext.Request.Headers["Referer"];
                }

                if (!string.IsNullOrWhiteSpace(originHeader))
                {
                    filterContext.HttpContext.Response.Headers.Add("Access-Control-Allow-Origin", originHeader);
                }
            }
        }
    }

Global.asax:
        protected void Application_BeginRequest(object sender, EventArgs e)
        {
            if(Request.HttpMethod == "OPTIONS")
            {
                 // NEVER
            }
        }
2
  • Why not simply use .NET's CORS middleware? No need to re-invent the wheel, unless you're planning to improve the official middleware. Commented Jan 20, 2023 at 16:55
  • 1
    @jub0bs because I am not using .NET Core, it is the .NET Framework 4.8 MVC. Commented Jan 23, 2023 at 10:21

1 Answer 1

1

Well...after a few hours of digging I finally found the answer by comparing it with another project that seemed to work when adding the code above in it.

The fix in Web.config is the following and it looks like IIS is eager to handle the OPTIONS requests, so we need to remove the OPTIONSVerbHandler and then ours (the one from Application_BeginRequest) will be considered.

    <handlers>
        <remove name="ExtensionlessUrlHandler-Integrated-4.0" />
        <remove name="OPTIONSVerbHandler" />
        <remove name="TRACEVerbHandler" />
        <add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="*" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
    </handlers> 

And final code:

        protected void Application_BeginRequest(object sender, EventArgs e)
        {
            
                var originHeader = "";
                if (((IList)Request.Headers.AllKeys).Contains("Origin"))
                {
                    originHeader = Request.Headers["Origin"];
                }
                else if (((IList)Request.Headers.AllKeys).Contains("Referer"))
                {
                    originHeader = Request.Headers["Referer"];
                }

                if (!string.IsNullOrWhiteSpace(originHeader))
                {
                    Response.Headers.Add("Access-Control-Allow-Origin", originHeader);
                }

                if (Request.HttpMethod == "OPTIONS")
                {
                    Response.Flush();
                }
        }
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.