I am using Microsofts EnableCors
Attribute for my Web API
calls. The client-side behavior runs as I would expect: e.g. the call returns as failed when the Origin is invalid.
However, when I put a break-point inside the method & call from an invalid Origin...the method still executes top-to-bottom (even though the client gets a failed result). If the Origin is invalid, I dont want it to execute AT ALL.
MY QUESTION IS:
How can I prevent the Web API method from executing AT ALL if the EnableCors Origin is invalid?
Help me Obi-Wan Kenobi...you're my only hope.
MY CODE LOOKS LIKE:
[HttpPost]
[EnableCors(origins: "www.zippitydoodah.com", headers: "*", methods: "*")]
public HttpResponseMessage Enqueue(HttpRequestMessage request)
{
// NONE OF THIS SHOULD RUN: If the Origin is bad...but (oddly) it is
TraceHandler.TraceIn(TraceLevel.Info);
string claimId = string.Empty;
ClaimMessage claimMessage = null;
try
{
claimId = GetClaimId(request);
claimMessage = CreateClaimMessage(claimId, segmentClaimFullName);
Enqueue(claimMessage);
TraceHandler.TraceAppend(FORMAT_ENQUEUED_SUCCESS, claimId);
}
catch (Exception ex)
{
TraceHandler.TraceError(ex);
TraceHandler.TraceOut();
EnqueueToPoison(ex, claimMessage);
return Request.CreateResponse(HttpStatusCode.InternalServerError, GetHttpError());
}
TraceHandler.TraceOut();
return Request.CreateResponse(HttpStatusCode.OK, string.Format(FORMAT_ENQUEUED_SUCCESS, claimId));
}
MY CONFIG LOOKS LIKE:
public static class WebApiConfig
{
#region <Methods>
public static void Register(HttpConfiguration config)
{
// ENABLE CORS
config.EnableCors();
// CREATE ROUTES
config.Routes.MapHttpRoute(
name: "DefaultRpcApiActions",
routeTemplate: "api/{controller}/actions/{action}/{id}",
defaults: new { id = RouteParameter.Optional });
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional });
}
#endregion
}
As it turns out...
CORS headers are not expected to PREVENT calls to a controller: MVC or Web API. It merely prevents the RESULTS from being returned to the browser. The method it will get executed no matter what...so you must prevent execution by other means.
WHAT OTHER MEANS?
You can probably do it using an
AuthorizeAttribute
. But I wanted to do it at the ACTION level, so I chose anActionFilterAttribute
- and performed checks in inOnActionExecuting
NOTES ON USING: The ActionFilterAttribute
Go ahead and open CORS to all & then restrict by action (so everyone can PING)
Assumes all calls come from a valid
REFERRER
This means things like
SQL CLR
calls from a database (which is what I am doing) won't work because theREFERRER
is null (because of this, I will be posting a better solution later).ICorsPolicyProvider
is useless - I am removing it (but included it here)All the examples I saw included it, but I have yet to find a scenario where it gets called. My constructor already creates the
CorsPolicy
& the policy is available throughout the calls lifetime...so theICorsPolicyProvider
method seems pretty useless (at the moment).The
TraceHandler
implementation is my own - go ahead & use your own insteadThe
Access-Control-Allow-Origin
header had to be added to ensure expected return-message behavior for certain clientsHERE IS THE CODE: The ActionFilterAttribute
HERE IS USAGE OF THE CODE: The ActionFilterAttribute
APPLICATION SETTINGS: The ActionFilterAttribute