Custom domains, SSL and Azure

I’ll walk you through the process of associating a custom domain with your Azure website and then configure a SSL certificate with that site.

The process itself is quite straight forward, but I ran across a few gotchas that I had to wrestle with but hopefully if you follow these steps then it should save
you a few hours from having to struggle with the same issue(s).

1) Create a Website in Azure – To configure SSL, you need to have at least a Basic plan, though you can configure custom domain is a Shared plan. Since I have already associated the 1229ToyWebApp with my custom domain www.ideaazure.com, the URL lists my custom domain, but initially, this URL will point to http://1229toywebapp.azurewebsites.net/

Untitled

Next search for domains in the Settings blade and select the bring external domains to display the bring external domains blade. Copy the IP address – as it says, this is the IP address we’ll use to configure the A record in GoDaddy.

Untitled

Let’s head over to Godaddy to configure DNS zone files – our record should look like this

Untitled

Notice the ‘Points To’ IP address in the image above is the same as the IP address that Azure generated for us and we bought this over from the ‘Bring External Domains’ blade – this is the IP address of our website 1229toywebapp.azurewebsites.net/

Next, add the following CNAME record, this one maps the custom domain name, in our case http://www.ideaazure.com to the 1229toywebapplication.azurewebsites.net subdomain.

Untitled

So, the above two records create the following mappings

Keep in mind that in the first CNAME record the @ symbol refers to the root domain i.e. ideaazure.com, and in the second CNAME record  

We now need to configure one additional CNAME record and this should look like this, and this is to let Azure know that you do indeed have control over your domain. So, the mapping below should be read as awverify.ideaazure.com points to awverify.1229toywebapp.azurewebsites.net

Untitled

Propagation of DNS entries can take up to 48 hours though you rarely have to wait that long, in my case it about 10 minutes.

Let’s now verify if the DNS entries have propagated successfully by heading over to the http://www.digwebinterface.com/.

Untitled

As you can see in the image the first A record and then the subsequent CNAME records all map correctly.

Next, go back to your azure portal and add the custom domain as shown in the image below. If you are able to save successfully then everything has gone according to plan and if you now type your custom domain in the address bar then your azure website should pull up.

Untitled

Next, let’s configure an SSL cert, there are a couple of different options. One is to use the makecert.exe and here’s a great article on how to do this, or you could go the route of using openssl. I chose to go with StartSSL .

Start with ‘Start Now for Free SSL Certificate’, click on authenticate and this takes you to a page where you can ‘Get the new Login Authentication Certificate’ and you are prompted to enter your email id. Once you do that a verification code is sent to your email. Take that verification code and enter it as shown in the figure below and then click on the ‘Get the New Certificate’.

Untitled

This is where things get a little interesting, on my Chrome version Version 49.0.2623.87 browser, the certificate could not be installed automatically and it then presents me with a couple of options, I chose the first option and entered the private key password.

Untitled

This takes you to a page that allows you to download the client site certificate and you should then be able to simply click on the downloaded certificate and install it in the browser. But on clicking on the downloaded certificate chrome would present me with a dialog saying ‘This file is invalid for use as the following: PKCS #7’. Remember, here all that StartSSL is attempting to do is load a client certificate which can then be used to authenticate the user rather than entering username and password.

Untitled

I then fired up my Opera browser and tried authenticating by following the steps listed above. Luckily, here Opera was able to install the client certificates transparently. Remember, you will have to go through all the steps listed above, starting first with ‘Get the new Login Authentication Certificate’ and entering your email Id. The client certificates are browser specific.

Now that you are registered for a free account and successfully logged in, head over to the Validation wizard tab and select the option for Domain Validation

Untitled

Enter the domain root that has to be validated

Untitled

Next you are presented with a few email addresses where the verification code can be sent, these are domain related email addresses or the email address recorded in the domain registration record.

Untitled

Select the email address you want the verification code to be sent to and then put that code you receive in the verification code box and select validation.

Now head over to the Certification Wizard tab, you are presented with a couple of option. Web server certs is what we want so select that option

Untitled

StartSSL supports the Subject Alternate Name X.509 extension, this allows us to set the common name to the fully qualified domain name i.e. http://www.ideaazure.com and the alternate name set to ideaazure.com.

Untitled

Next use the click on the StartComTool.exe, this will download the StartComTool executable. Run this executable and you should be presented with a dialog as shown below

Untitled

Click on generate CSR, it will prompt you to give a name to the generated key file, do so and save it.

Next, copy the CSR content that you see in the StartCom tool and paste it in the box as shown below

Untitled

on clicking submit, you should be presented with an option to see a list of certificates that have been generated.

Untitled

and, selecting the certificate list above should show a display similar to this

Untitled

On selecting retrieve a zip file will be downloaded, extract its contents. You’ll notice 4 folders – otherserver.zip, NginxServer.zip, IISServer.zip and ApacheServer.zip. Obviously, we’re after the IIServer.zip. Extract this file – you should see two files – 1_Intermediate.crt and 2_your_domain.com.crt.

Now, select the ‘Create PKCS#12 (PFX) file’ option. This should take you here

Untitled

If you recall, a little earlier, we saved the private.key file while using the StartComTool.exe. Copy the contents from that file and paste it in the ‘Enter private key’ box and paste the contents of 2_your_domain.com.crt file in the ‘Enter Certificate’ box. And also provide a password and select submit.

You should see the following screen, select download and rename the extension of the downloaded file to .pfx

Untitled

Head back to the azure portal and in the ‘Custom domains and SSL’ blade select the Upload Certificate option. This should display the Upload Certificate blade. Upload the recently saved pfx file and enter the password you used while creating the pfx file. Once you click on save you should see a ‘ Successfully updated web app settings’ message.

Untitled

You should now be seeing the newly uploaded pfx certificate in the list of certificates

Untitled

All that is left is to associate that certificate with our custom domain in the ‘SSL bindings’ section.

Untitled

When you click on save, you’ll be given a warning that ‘Adding SSL bindings may have a pricing impact. Continue?’ And, then on selecting ‘OK’ you should see a ‘Successfully updated SSL bindings’ message.

That’s it! On navigating to your site using the https protocol, you should see the green lock.

Untitled

AngularJS + ASP.NET Web API: Building a simple grid in AngularJS with server-side paging, sorting, searching (Part 8)

This post will be the culmination of all of the following posts:

In part 1 I described how to configure the application to include the requisite JavaScript files, laid out the folder structure & stubbed out the app.js and a few other JavaScript files.

In Part 2 I populated the grid with data returned from the Web API.

Part 3 of the post incorporated the ability to page through the grid.

In part 4, I added a loading bar / progress bar

In part 5, we took a brief detour and I spoke about unit testing

Part 6 – we saw how to sort records

And, Part 7 – added the ability to search based on first and last names.

In this post – part 8, I’ll be adding the ability to edit a record in-place as well as delete a record, and also add a new record.

Let’s start by writing the functions that will handle the deleting a record and updating an existing record or adding a new record.

Continue reading

AngularJS + ASP.NET Web API: Building a simple grid in AngularJS with server-side paging, sorting, searching (Part 5)

Before we delve into implementing sorting and searching, I would like to spend some time on unit testing. Unit tests for me are fundamental to any software development endeavor. I’ve been in the trenches long enough to know the importance of writing unit tests. The presence of unit tests also shows discipline & there is a positive correlation between unit tests and code quality. In my opinion writing unit tests is sacrosanct to the discipline of crafting software. Period.

So, now without more ado, let’s see how one can unit test angular code. There is some setup required. First, add a new project of type “Unit Test Project” and name this project NgWebApiGrid.Web.Tests.

Next, install Chutzpah; Chutzpah is a test runner and without this add-on the JavaScript unit tests you write in say Jasmine will not get recognized i.e. they will not appear in the Test explorer. Chutzpah is available as a Visual Studio add-on and to install it go to Tools menu option and then select extensions and updates

Continue reading

AngularJS + ASP.NET Web API: Building a simple grid in AngularJS with server-side paging, sorting, searching (Part 4)

In the previous post I implemented paging and in this post we’ll implement a nifty Angular plug-in called angular-loading-bar. But before we proceed there is one thing I wanted to correct in my previous post. In the students.tpl.html file we added the pagination directive as so


<pagination data-total-items="totalItems" ng-model="currentPage" data-max-size="NumberOfPageButtons" class=" pagination-sm" data-boundary-links="true" data-rotate="false" ng-change="pageChanged()" data-items-per-page="recordsPerPage"></pagination>

And, though this works just fine it will not pass HTML validation and you might have noticed squiggles below “pagination”. This was bothering me quite a bit, so to correct this convert the pagination custom tag to a span & then use attributes to initialize the pagination custom directive as so


<span data-pagination data-total-items="totalItems" data-ng-model="currentPage" data-max-size="NumberOfPageButtons" class=" pagination-sm" data-boundary-links="true" data-rotate="false" data-ng-change="pageChanged()" data-items-per-page="recordsPerPage"></span>

Now that we have that out of the way, let’s go to the home page of the loading bar we will be using. While this page was loading you might have seen a blue colored bar run across the top of your screen from left to right. We’ll incorporate this in our application such that each time there is a delay due to an XHR request the loading bar should show up.

Continue reading

AngularJS + ASP.NET Web API: Building a simple grid in AngularJS with server-side paging, sorting, searching (Part 3)

In the previous post I populated the grid with data returned from an API, and in today’s post I’ll incorporate paging.

Head over to http://angular-ui.github.io/bootstrap/ & from the directives dropdown select “pagination”

You should see a set of pagination controls – each styled a bit differently, feel free to take a look at the markup and JavaScript & play with them in plunker to get familiar with how they work.

I like the one that limits the maximum number of visible buttons – so go ahead and copy the markup, I’ve highlighted the markup we’ll be copying below

NgWebApiGrid19

Paste this markup below the closing </table> tag in the students.tpl.html file as so

Continue reading