Friday, 21 December 2012

The provided URI scheme 'https' is invalid; expected 'http'

A really annoying error which is hard to understand until it is explained and then it makes perfect sense!
I was getting this on Azure when calling from a web application to a web service.
What it means is that the client endpoint you have specified (the "provided URI") has a scheme of https at the begining (the client url is https://whatever) whereas the meta-data for the endpoint that you probably added with "Add Service Reference" discovered that the protocol was http on the service binding. I got this with a client config in the web app of:

<endpoint address="https://6ead981357238479hfc0beff3193e7b.cloudapp.net/WebService.svc/standard"
    binding="wsHttpBinding" bindingConfiguration="standard" contract="IWebService"
    name="standard">
    <identity>
      <servicePrincipalName value="host/RD00443D49795E" />
    </identity>
  </endpoint>

And a service configuration of:

<binding name="standardConfig" maxReceivedMessageSize="65536000">
  <readerQuotas maxDepth="32"
                maxStringContentLength="65536000"
                maxArrayLength="65536000"
                maxBytesPerRead="65536000"
                maxNameTableCharCount="65536000" />
</binding>

The fix is either to specify http on the client endpoint in the web application or to add <security mode="transport"> to the binding on the web service:

<binding name="standardConfig" maxReceivedMessageSize="65536000">
  <security mode="Transport"></security>
  <readerQuotas maxDepth="32"
                maxStringContentLength="65536000"
                maxArrayLength="65536000"
                maxBytesPerRead="65536000"
                maxNameTableCharCount="65536000" />
</binding>

If you do modify the service binding, you will need to update the service reference on the web app to ensure it now knows that the expected scheme is https.

Thursday, 20 December 2012

Why Process is Not the Enemy of Agile

The thing I don't like about words like Agile is that they can mean many different things to different people and organisations. We band about questions like, "do you do agile" as if there is really a single answer to that and that brings in confusion. Ultimately, of course, the intention of an agile programming methodology is that the supposedly skilled programming workforce are not restricted (too much) by management or budgets or programs that are imposed from above by people who don't necessarily know how long something takes. It also aims to be able to react quickly to changes either in requirements or in technology. Of course this is a welcome idea but is in danger of being elevated to some kind of holy grail that trumps anything else, however sensible.
I am talking about process and this is something I hold dear and don't personally believe to be the enemy of agile since process is whatever you make it to be and it should support the best parts of your development rather than cause a lack of agility. Naturally it is easy to over-use process and my question to any part of any process is quite simply, "what does this achieve?". A simple question and one which should be easy to answer by anyone using it. If a programmer cannot answer why, for instance, they have to do a code peer review, then they should ask their manager, if they don't know then it should be dropped because processes with no point causes frustration and definite lack of agility, correct processes, however, do not.
I read today a quote from David J Bland who said, "If your startup is going to get stupider as it scales, I understand why you feel the need to layer on process.", a nice pithy quote that is easy to tweet and retweet but one which sadly misses the point (or perhaps I misunderstand the quote). It is not just stupidity that process is to protect against but human nature including lack of experience, forgetfulness, poorer inter-team communications and corner-cutting. You've heard the phrase, "fool me once, shame on you. Fool me twice shame on me" and the same could be said about software, "make the mistake once, shame on you. Make it twice, shame on the process". To assume that you can ignore process as teams grow is extremely naive. As a lone developer, I know fairly well what I can do well and what I need someone else to check. I know when I am being lazy and need to revisit something and more importantly, I am fully responsible for the entire system because I write it all. This means I can use precisely what tools and checks I need to overcome my own weaknesses and also I know how all the parts interact, there is no communication or understanding issues. Even though I have this luxury, I like checklists for setting up servers so I don't forget to close firewall ports and I like code review checklists that remind me to translate strings and validate web pages before they are processed. I have a process and I am only a 1 developer team, you cannot tell me that any team does not need one.
People sometimes take small or trivial software companies and try and scale this to a multi-national corporate as if they are the same thing. Agile is great for things like Facebook, although they now have enough people to both review things and also to quickly pull the plug on something that doesn't work. Microsoft likewise were agile in the first years but now have thousands of testers so whether they have a good process or not can be covered up (although inefficiently). To assume, however, that your company would win a contract for a banking system or nuclear control system despite not having a process because it is "not agile" is plain wrong.
Process is not the enemy of agile, poor process, however, is the enemy of all industry.

Wednesday, 19 December 2012

Self-signed SSL certificates and Windows Azure

I am new into the world of Azure. What I like is the supposed ease of deployment directly from Visual Studio and also the fact that we got a very generous free trial for 2 years!
Anyway, making things easier has its downsides. It has to invent new ways of doing things that I already know how to do the long-winded but well-known old-fashioned way. One of these is handling TLS/SSL certificates for secure web-sites - something I personally think should be enabled on all sites in this day and age.

Anyway, I had a site deployed onto Azure which was working fine on http but not enabled on https. Once I have https enabled, I will modify the deployment to rewrite all non-ssl requests to redirect to the ssl one (something I'm sure will warrant a future article).

Anyways, I am personally testing this system and the urls will change at some point soon so I didn't want to buy any proper ssl certs just yet. Making self-signed certs is easy enough but when I tried, I deployed and got an error attempting to access the SSL endpoint even though it worked locally, the reason being I hadn't created the self-signed cert properly and I think locally, the system detects this and uses the built-in Azure testing certificate instead.

I had used a guide from a blog post which was obviously not too accurate, so anyway, I eventually found this blog post: www.theworkflowelement.com which correctly stated the way to create these certs, in this case directly into the local certificate store. So here are the steps from start to finish to self-sign and deploy an SSL binding to your web site into Azure.

Following the blog post (from the Start Menu: Visual Studio 2012->Tools->Command Prompt), first create a certificate using:

makecert -a sha1 -n "CN=lkhjasd908d0iqdaljds.cloudapp.net" -pe -r -sky exchange -ss My -sr LocalMachine  

(Note that the My and the LocalMachine relate to the local certificate stores and should stay as-is. Make the common name equal to whatever your site url is in the staging area of the azure portal)

 

Run up mmc.exe from the start menu and choose File-Add/Remove Snap In. Double-click "Certificates" in the left hand list and choose Computer Account (which is where you just told makecert to put the certificate it created). Choose next and then leave Local computer selected and press finish. Press OK to close the Add/Remove dialog and browse to Certificates->Personal->Certificates

Find the certificate you just added which will have IssuedTo set to the common name you set earlier (xxxxxxxxx.cloudapp.net) and right-click it choosing All Tasks-> Export... Click next and choose that you DO want to export the private key and click next. Use the .PFX selection and include all certificates in path if possible then click next. Enter a password for the private key - best to make it strong. Repeat the password and click next and then choose a filename to export to. Click next and finish at the summary screen - hopefully you will get a success message.

Go back into the azure portal and choose the correct instance for the common name you created the key for (don't get site/key confusion!) and then choose the certificates 'tab':

 
My screen shot shows the certificate I have already uploaded (suitably obscured!) whereas yours won't show anything yet. Choose Upload at the bottom of the screen and browse to the .pfx file you just created and type in the password you set for the private key. This should upload and do nothing else particularly interesting.

Next you have to setup your cloud project. I assume you already have a cloud project that has already been deployed and tested over http. I ask because I had problems with https and then realised I had broken my site locally!

Find the relevant role for your project (e.g. your web role) and double click to open the configuration.

 

Start in the certificates tab and click Add Certificate. You can use any name here to refer to it. Leave the dropdowns at LocalMachine and My (where you put the original certificate) and then click the ellipses button next to the thumbprint text box.  This opens a funny looking dialog which lists the certificates you have in this location and allows you to choose one and press OK:

 

This should have filled in the thumbprint field for you. It is worth quickly checking this against the Azure portal certificates tab for the site you are working on and make sure the two thumbprints match. If not, you might have mucked up the certificate creation or more likely have got certificate confusion and either uploaded the wrong one to Azure or selected the wrong one locally.

Then you can click on the endpoints tab and add a second endpoint which is basically the same as the first but with https and port 443 selected. You should also select your newly added certificate for this ssl binding.

Click on the configuration tab and tick the box for "Launch browser for" and https. Build the solution in release mode (since I hope this is what you will be deploying) right-click your cloud project and "Set as Startup Project" if not already done. Press Debug (F5 for me) and ensure that both pages open in your browser, an http one and an https one. You should see a browser warning since your self-signed certificate both doesn't match the local URL and is not part of a trusted chain to a root authority (no worries - this is for test only).

If that is OK, deploy your web site to Azure in the normal way and after the few minutes it takes to upload, open up the URL in your browser and change the http to https. You should see a browser warning that the certificate is not part of a trusted chain but this time, the certificate URL SHOULD match the actual URL. If it doesn't work, you might have produced an incorrect type of certificate (it needs to be "exchange") and if you get a warning about the URL, you might have typed this incorrectly in the original makecert call. Other than that, it should all work.

Once you are all done and into production, you should get proper certificates for the sites either from a public root authority or otherwise if it is a private network, you should use your corporate certificates which will/should be trusted on all of your internal machines.