by Néstor Guadarrama
Recently, a Customer asked me about if they could encrypt and/or decrypt all connectionStrings stored on "Application Settings" sections for their Windows Azure Websites. The basic context of such request is that they have a development team on site, but also, they have some external developers working with them, so they don't want to keep sharing information about Database connections (production stage) with too much people.
From security perspective, this is the right way to control who can get access information to database connections parameters, the site, but from IT operations perspective, this is a nightmare because unlike Windows Azure Web Roles, Windows Azure Websites doesn't offer a way to restrict access to specific users/groups from resources or services provided by the portal, unless Customer implements Windows Azure Active Directory, enabling single sign-on to simplify user access.
Other way path to take (the best for me) should be Continuous Integration approach in order to have control of what developer are testing/doing on application being deployed to Windows Azure Websites. Windows Azure Website can integrate with many well-known repositories like Git and frameworks to keep developers working together as a team.
But also, even thou the fact that Customer could implement Windows Azure Active Directory or Continuous Integration, there is another caveat: the publish profile file. All developers working with Windows Azure Websites knows that, in order to start connecting, building and deploying websites, they need some credentials (provided by Windows Azure trough profile file) for connecting to their SCM console using Visual Studio/ FTP clients or WebDeploy engine:
As you can see on profile file, parameters for database connections are empty. This is because, I didn't enter connectionStrings using my Windows Azure Web Portal Management. Instead, my web.config file has stored my connection string inside of it:
Following the standard procedure, if I remove my connectionStrings section from web.config file and I enter this value on configuration section for the website, this is what is happening:
Now, when I download again my publishing profile settings, I got:
The best way to ride of this dilemma is using Staged Deployment on Microsoft Azure Websites. When you deploy your application to Azure Websites, you can deploy to a separate deployment slot instead of the default production slot, which are actually live sites with their own hostnames. This option is available in the Standard web hosting plan. Furthermore, you can swap the sites and site configurations between two deployment slots, including the production slot. Because every deployment slot is actually an Azure Website itself, developers can get access only to those deployments that they need without compromise production environment.
Because Customer is not using Windows Azure Cloud Service, there is no way to hide the connection string from your web.config file, unless you can apply several developer tricks into the code. In order to test this encrypt/decrypt scenario, I tested it using the Kudu console. To access your Kudu console, using your deployment credentials, navigate to https://*****.scm.azurewebsites.net where ***** is the name of your Windows Azure Website. Once authenticated, you should see a page similar to next figure:
In order to test the encryption, I added again "connectionString" section it to the web.config file. Using aspnet_regiis.exe utility already installed on my environment, I encrypted the connectionStrings section for my web.config file:
You can visualize your web.config file from Kudu. This is how section connectionStrings looks like after encrypt the entire section:
Using the same approach, I decrypted connectionStrings sections, you can use next command:
And this is how web.config file looks after decryption:
Now, you can remove the connectionString section on your Windows Azure Web Portal Management, in order to avoid transfer user credentials inside of publishing settings file:
When you download your publishing profile file, the file doesn't content any information about connectionStrings at all (parameters are empty):
This process has several caveats:
- You need to customize your deployments in order to avoid override web.config file for every deployment that your team will do, because if you override the web.config file with new features/values, you will need to follow this procedure every time.
- This process only works with ASP.NET web applications. Websites developed using PHP, JSON or any other framework, doesn't store connection strings on web.config file.
'til next time!