CORS Preview Handling in Asp.net Frontend

I have three applications in my architecture.
They are on the same server but have different port numbers.

A - Token Application (port 4444) - Asp.net WebApi
B - API Application   (port 3333) - Asp.net WebApi
C - UI Application    (port 2222) - AngularJS App.

      

Application flow looks like below

1. The UI project gets a token from the Token application (this requires Windows Auth.) Example: awxrsdsaWeffs12da

2- The UI app puts this token in a custom header called "accessToken"

Example: accessToken: awxrsdsaWeffs12da

3-user app sends request to API app Example: http:myaddress:3333/api/TheRestServiceHere

UI app gets 401 error which dispatches OPTIONS method. (I think preliminarily)

In my web api project, I have included Cors as shown below.

public static void Register(HttpConfiguration config)
{
            ....

            //CORS
            var cors = new EnableCorsAttribute("*", "*", "*");
            config.EnableCors(cors);

            ....
}

      

Configuration

   public static class WebApiConfig
    {
        public static void Register(HttpConfiguration config)
        {

            //CORS
            var cors = new EnableCorsAttribute("*", "*", "*");
            config.EnableCors();


            // Web API routes
            config.MapHttpAttributeRoutes();

            config.Routes.MapHttpRoute(
                name: "DefaultApi",
                routeTemplate: "api/{controller}/{id}",
                defaults: new { id = RouteParameter.Optional }
            );


            var json = config.Formatters.JsonFormatter;
            json.SerializerSettings.PreserveReferencesHandling = PreserveReferencesHandling.None;
            json.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
            json.SerializerSettings.Formatting = Formatting.None;
            json.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();

            config.Formatters.Remove(config.Formatters.XmlFormatter);
        }
    }

      

So I am looking for a solution to call Application API controllers (B) and get 200 :)

Hello

+3


source to share


3 answers


I have fixed this in an application I am working on by creating a module that responds to requests that use the OPTIONS verb. You should probably change it a bit to include the verbs and the type of content the app is requesting. In my case, I decided to post everything as JSON (which requires prior validation). The module looks like this:

public class OptionsModule : IHttpModule
{
    public void Init(HttpApplication context)
    {
        context.BeginRequest += (sender, args) =>
        {
            var app = (HttpApplication) sender;

            if (app.Request.HttpMethod == "OPTIONS")
            {
                app.Response.StatusCode = 200;
                app.Response.AddHeader("Access-Control-Allow-Headers", "content-type");
                app.Response.AddHeader("Access-Control-Allow-Origin", APISettings.ApplicationOrigin);
                app.Response.AddHeader("Access-Control-Allow-Credentials", "true");
                app.Response.AddHeader("Access-Control-Allow-Methods", "POST,GET,OPTIONS");
                app.Response.AddHeader("Content-Type", "application/json");
                app.Response.End();
            }
        };
    }

    public void Dispose()
    {
    }
}

      

Then you need to register it in your web.config:



<system.webServer>
    <modules>
      <add name="HandleOptions" type="namespace.OptionsModule" />
    </modules>
</system.webServer>

      

Another thing you might want to do is specify an explicitly permitted origin. Chrome doesn't like to have a wildcard.

+8


source


One of my friends solved the problem using OPTIONSVerbHandler.

When the UI app wants to use the GET method , the browser sends the OPTION to the server first (pre-flight). Then, if the Preflight request is ok, it sends a GET request .

OPTION REQUEST - PREFLIGHTGET REQUEST - AFTER PREFLIGHT

For CORS testing purposes, we used the following code to send the GET method .

<html>
<head>
    <script src="https://code.jquery.com/jquery-1.9.1.min.js"></script>
    <script>
    $( document ).ready(function() {
        var adress = "http://10.10.27.36:3434/backend/api/role";

        $.ajaxSetup({
            headers: { 
            'Content-Type': 'application/json',
            'accessToken': 'some value',
            'Origin' : ''
            }
        });

        $.ajax({
        type: "GET",
        url: adress,
        dataType: "json"
        });

    });

    </script></head><body></body></html>

      

To handle the OPTION method sent by the browser before the GET, you must have the following settings. enter image description here

1- Webconfig



<system.webServer>
    <handlers>
        <add name="OPTIONSVerbHandler" path="*" verb="OPTIONS" modules="ProtocolSupportModule" resourceType="Unspecified" requireAccess="None" />
    </handlers>
</system.webServer> 

      

2- Adding OPTIONSVerbHandler with the following settings

enter image description here

Restrictions on request enter image description here

enter image description hereenter image description here

3- Our header settings have an accessToken which is normal as you can see

enter image description here

+3


source


For Azure environment

You need to allow origin from the portal.

Azure Cors settings

0


source







All Articles