find a location for property in a new city

Tuesday, 22 December 2015

Stop processing OPTIONS requests for CORS in ASP.NET Web API

I was attempting to allow some particular origins to access my ASP.NET Web API from a client side single page application. I was using the EnableCorsAttribute that comes with the Microsoft.AspNet.WebApi.Cors NuGet package.

I managed to set up CORS using the following code in my WebApiConfig:

var origins = ConfigurationManager.AppSettings["AllowedOrigins"];
var cors = new EnableCorsAttribute(origins, "accept,content-type,origin,customId", "GET,POST,PUT");
config.EnableCors(cors);

There is quite a lot to CORS but essentially, (some browsers) send a pre-flight request recognised with its HTTP method OPTIONS. This basically asks the application who is allowed to access this URL with the attempted headers and HTTP method. Your Web API will respond saying which origins are allowed or if there are any errors. The browser then decides if it is one of those allowed origins and sends the request if it is.

The problem I found is that on this initial OPTIONS request my IoC container, Unity, was constructing a whole dependency chain of classes. Some of which access the database and some check HTTP headers. This was throwing an error since bits were missing from the HTTP headers that would be with normal requests and unnecessarily hitting the database. So really, I wanted to stop these requests in their tracks whilst making sure they did their intended pre-flight work.

The best way I found to do this was to ignore routes based on an HTTP constraint for "OPTIONS". Basically shove this in your routing:

var constraints = new { httpMethod = new HttpMethodConstraint(HttpMethod.Options) };
config.Routes.IgnoreRoute("OPTIONS", "{*pathInfo}", constraints);

More info on Enabling CORS in Web API.

Follow britishdev on Twitter

Thursday, 6 August 2015

Outbound IP address from Azure WebJobs or WebSite

I need to find the outbound IP address of an Azure Website so that I can whitelist this IP address in a service I wish to call. However there are concerns with this practice as I will explain.

Azure WebJobs are completely awesome and they should be used more. I have project however that I am using to pre-process a large amount of data. As part of this process, my Web Job will need to call a third party web service that operates an IP whitelist. So to call it successfully I need to find the IP address of my Azure WebJob.

That is simple enough, I confirmed the IP address using two sources, one is a given list of IP's as documented by Microsoft. Details on how to find yours are here: Azure Outbound IP restrictions. I also wrote a little code to make sure this matches from a WebJob like so:

public async static Task ProcessQueueMessage(
    [QueueTrigger("iptest")] string message,
    TextWriter log)
{
    using (var client = new HttpClient())
    {
        var response = await client.GetAsync("http://ip.appspot.com/");
        var ip = await response.Content.ReadAsStringAsync();
        await log.WriteAsync(ip);
    }
}

Popping something in the "iptest" queue kicked off the job and checking the logs confirmed the WebJobs are in fact consistent with the IP ranges documented.

There is a problem however, if you read that link you will discover that although it is roughly static it is not unique. You will share your outbound IP with other users of Azure WebSites that are hosted in the same region as you and the same scale unit as you. What is a scale unit? Who cares but there are 15 of them in the North Europe data centre for example so not a lot. Now how secure do you think IP whitelisting a shared IP is? Not very!

Workaround

Don't give up hope! The work arounds I can see are to ask the service provider to not rely on only IP whitelisting, have another form of authentication, an API key over SSL would work for example. Have it as well as IP Whitelisting if it makes them happy.

If they can't be controlled you can do your own magic. There are proxy providers out there that will provide your calls with a unique static IP address. Try QuotaGuard. Or make your own - if you already have a Cloud Service running in Azure you can proxy the service via that as they can have static and unique outbound IP addresses.

Follow britishdev on Twitter

Skipping unit tests is a false economy

You only need unit tests if you write buggy code but why would I write bugs? I don't need them.

For a long time I thought unit tests was just vanity code. Oooh look, I've made this repository unit testable and I've used my fav' IoC container to inject dependencies now so in my tests I mock them to create and elegant suite of unit tests. No one will ever run the tests but it is cool because all the top dev bloggers write about it.

That is probably a lot of people's motives, that and the lead dev told them to. You can tell when people don't fully understand why they are writing unit test when they are running short of time to complete their work and the first thing they compromise is the unit tests. Unit tests are always the first to be dropped in high pressure environment.

Let me sell unit tests to you

They save you time! How can that be right? They take so long to write and refactor every time you change your code. Unit tests save you time because you no longer need to trawl through mountains of code to work out in you head any possibility for causing a bug. You don't need to step through every line of code in your application finding potential for unexpected consequences when you have decent unit test. Which saves so much time!

Worse still is the people that wouldn't have trawled through the code to find a potential bug and just committed their code anyway and broke something. Sooner or later it will get noticed and someone is going to spend a very long time tracking it down and then fixing the root cause.

What about deployment time as well, when you come to merge and commit a branch or do a deployment, how long would it take you to review every line in the merge or click about every section of the site? 30mins? Hours? Or maybe you wouldn't bother and as mentioned that is when the even harder to find bugs creep in. It is such a waste of time!

Writing unit test from the beginning will slash all this wasted time!

Unit tests should be the first things your write!

This is called TDD (Test Driven Development) and it is the most effective way of ensuring your tests get written as you can't drop them out to save time as they are already written. It also forces you to really think about your code before writing it.

But TDD or not, please PLEASE write them. Lots of them. Use NCrunch that has continuous test runners for your test suite and shows the lines of code covered and the state of that test. Aim for 80%+ code coverage from the beginning and you will save so much time in the future doing all that boring clicking about or line by line reviewing of your code merges.

Not writing unit tests is a false economy

And developers are expensive so don't waste their time.

Please send this on to your team including the project manager. Everyone must know the importance of getting unit tests done and written well.

Follow britishdev on Twitter