I have three applications in my architecture.
They are on the same server but having 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.
The application flow is like below
1- The UI project gets the token from Token Application (It requires Windows Auth.)
Ex : awxrsdsaWeffs12da
2- UI application puts this token to a custom header which is named as "accessToken"
Ex : accessToken : awxrsdsaWeffs12da
3- UI application sends a request to API Application
Ex: http:myaddress:3333/api/TheRestServiceHere
UI application gets 401 Error. Which sends OPTIONS method. (I guess preflight issue)
In my web api project I enabled Cors like this below.
public static void Register(HttpConfiguration config)
{
....
//CORS
var cors = new EnableCorsAttribute("*", "*", "*");
config.EnableCors(cors);
....
}
Config
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 API application (B) controllers and get 200 :)
Regards
I fixed this in an application I am working on by creating a module that responds to requests that are using the OPTIONS verb. You should probably modify it a bit to include the verbs and content type that the application is requesting. In my case, I decided to post everything as JSON (which requires the pre-flight check). The module is as follows:
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 may want to do is specify the allowed origin explicitly. Chrome doesn't like having a wildcard there.
One of my friend solved the issue by using OPTIONSVerbHandler.
When UI application wants to use GET method, browser sends OPTION method first to the server (Preflight). Then if Preflight request is OK it sends GET request.
For CORS test purpose we used the following code to send 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 OPTION method which sends by browser before GET you should have the following settings.
1- Webconfig
<system.webServer>
<handlers>
<add name="OPTIONSVerbHandler" path="*" verb="OPTIONS" modules="ProtocolSupportModule" resourceType="Unspecified" requireAccess="None" />
</handlers>
</system.webServer>
2- Adding OPTIONSVerbHandler with following settings
Click on request restrictions
3- Our Header Settings we have accessToken which is custom as you can see
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With