In this article we will explore how to host an ASP.NET MVC application using multiple ADFS integration in Microsoft Azure WebApps and Cloud Service web role.
This involves the following steps –
- Acquiring Azure Subscription
- Publish application using Web Deploy option to Azure web Apps and access over https
- Convert application to Cloud Service type of project
- Publish cloud service to Azure from Visual Studio
- Run the application and observe the result.
Note: This article is in sequence with the previous published articles. The source code for this article is referenced from 3rd part of the series.
If you are following the complete series, then please note that this article is Part 4 of a series of articles that highlights the following important scenarios –
1. Configure ADFS in Azure VM
2. Implementing ADFS (or WSFederation) based Single Sign-On authentication in MVC based ASP.NET application using Windows Identity Foundation (WIF or in Developer language – specifically using System.Identity.dll)
3. Configure ASP.NET MVC to use Multiple ADFS using OWIN KATANA
4. Hosting ASP.NET MVC application integrated with multiple wsfederation to Azure WebApps (formerly Azure websites) and Azure cloud Services (Current article)
5. Making life simple – use 3rd Party (Paid) Identity Server Provider Auth0 to achieve multiple WSFederation (or ADFS) authentication in ASP.NET MVC application. [Coming soon].
In this article, we will highlight the procedure of hosting multiple ADFS integrated MVC project in Azure Web Apps and Azure Cloud service web role. In Part 1, 2 and 3 we have used the management portal of Azure to carry out each and every operation. For this article, we will use new Azure portal (http://portal.azure.com ) as in the future, the https://manage.windowsazure.com will be deprecated.
Applicable Technology Stack
1. Valid Microsoft Azure subscription. Free trial is available here.
2. Self-Signed SSL Certificates
3. VS 2013 with update 4
4. Azure SDK 2.6 and above
If you remember from Part 3 we have an ASP.NET MVC application which is integrated with two Azure based ADFS - Antakish.com and IndiaUniverse.com. Now we need to host this multi ADFS configured application in Azure Web Apps and Azure cloud services.
Creating Web Apps in Azure portal
In this section, let’s understand various options available in new Azure portal for website creation.
Provide DNS name for Web Apps
First let’s create web app DNS name in Azure management portal. Open the new portal of Azure from the link – http://portal.azure.com. Click on “New > Web + Mobile > Web App”. A new blade appears with many options shown below –
Let’s understand these options one by one. The first textbox is where we enter the Name of web app. As the extension of cloud service created in earlier series articles got *.cloudapp.net extension; for web apps, we get *.azurewebsites.net extension. The entered name is multiadfssample so my DNS name becomes multiadfssample.azurewebsites.net.
Select the App Service Plan
App service plans are very similar to Web Hosting Plans we had in Azure WebSites. The plans represents set of features and capacity that can be shared across your application hosted in web apps based on selected pricing tier. For this demo, we are going to create new App Service Plan therefore click on “Create New” button and put the name of plan as my-multi-adfs-plan.
Every App Service Plan has a name and Pricing Tier associated with it. We have already provided the Name, so now we must choose the Pricing Tier. Depending on the pricing tier selected, you get more or less features.
The UI of App Service Plans is excellent and it helps you in quick decision making. As you can see in the following screen, the portal shows you some recommended tiers and their associated features. So for Basic tier, we will have the most basic features, but for Standard we get additional feature like automated backups. In case of Premium, we get all features Standard tier has + more space. Of course Basic tier is cheapest whereas Premium tier is the costliest.
Now looking at the current pricing of tiers, you can feel it is still costly and you may want to look for cheaper options. So click on “View All” button and there it is!! An absolutely FREE Tier is present at the bottom as shown below. As we are just going to host our demo, and don’t need any special features; Free tier is perfectly suited for us. So select the FREE tier as shown below –
Select Resource Group
Any enterprise application in Azure is generally comprised of many components such as web app, database, database server, storage and so on. If any operation is required to be performed, then it has to be done individually for one resource/ component at a time. So if the application is complex and made of many resources, then managing these resource individually becomes a complex task. Therefore in the new Azure portal, a concept is introduced called as Resource Groups. This concept helps in managing all the resources of one application together. Azure resource group uses Azure Resource Manager for grouping of multiple resources as a logical group, within the boundary for every resource contained within it.
For this demo, click on “Create New” and provide the name of resource group as MultiAdfsResources.
Select Subscription and Location
The Azure subscription is always associated to a directory and directory is always associated to a Microsoft account. The tree hierarchy explaining the relationship is as below –
So select the subscription of your choice and data center. I have selected as South East Asia because it is the nearest region to India as of today.
Create Web Apps
Now click on “Create” button to complete the web apps creation. After web apps creation, a notification is shown on the left hand panel as shown below –
The notification blade shows the status of every action performed on new portal. As you see in the screenshot, a consolidated view of all notifications can also be viewed along with details from “Audit Logs” button. Another important point to note here is that a successful message is displayed about deployment to resource group and not individual web apps creation. I think this is a big change in perspective of Azure components management. If we click on the notification, then the resource group directly opens in a blade as shown below –
Deleting non required resources – Application Insight
As you can see in the resource group, currently it contains 2 resources. One is web app and another is Application Insight instance with same name as that of web apps. As of now, we don’t need any type of monitoring for web app therefore it is wise to delete this Application Insights resource. Therefore select or click on Application Insights instance. This opens up a blade with settings for Application Insights. In the top ribbon, simply select “Delete” and it will be removed from resource group.
So now we have only one resource that is web app multiadfssample in our resource group MultiAdfsResources. If you browse through URL http://multiadfssample.azurewebsites.net/ then you get default page from Microsoft Azure. Now we need to deploy our multiple ADFS configured MVC application to Azure Web apps.
Application and ADFS configuration changes for Azure Web Apps
Before understanding what changes we will need in our ADFS and application, let’s first understand a conceptual view of what we have done so far in Part 1, Part 2 and Part 3.
As you can see in the above diagram, the localhost MVC application is having trust relationship established with Antariksh and IndiaUniverse adfs by adding it as relying party. Similarly metadata URL of both ADFS is being used in local MVC application. As we know the URL of localhost application https://localhost:44314/ is the one using which ADFS knows to which application, the claim has to be sent.
Configuration changes on ADFS
Right now ADFS does not have any information of the Azure hosted WebApp application, so none of the ADFS will send claims after successful authentication. That’s why we need a change in ADFS to make it trust Azure WebApp URL. Now in Web app scenario, the URL is http://multiadfssample.azurewebsites.net/. So we need to let ADFS know about this URL so that they can send claims to it. In other words, now we need to form two-way trust between Azure webapp and ADFS by configuring Azure webapp URL as new relying party. Steps required to configure Azure webapp as a relying party are exactly similar to that present in “Part 3 under section Adding OWIN Katana based MVC app as relying party trust in ADFS along with screenshots.” The only change is in values and URL. So below are the values we should be using for adding Azure Web App as a relying party in Azure based ADFS – Antariksh and IndiaUniverse.
1. Open Server Manager-> Tools-> ADFS Management. Expand “Trust Relationships” from left hand panel and select “Relying Party trusts” option.
2. Click Next on Welcome screen and then select the option “Enter data about relying party manually”.
3. Provide display name as “Azure WebApp” and click Next. Then select “Adfs Profile” and click Next.
4. Skip Tone Encryption Certificate screen by clicking Next.
5. Select the option “Enable support for Ws-Federation Passive Protocol” and provide the URL of webapp as - https://multiadfssample.azurewebsites.net/Account/LoginCallbackAntarikshAdfs and click Next. Please note that the URL is https and not http.
6. Click Next on “Configure Identifiers” screen. Then select “I do not want multifactor authentication” and click Next.
7. Select the option “Permit all users to access this relying party” option and click Next. Click Next on “Ready to Add Trust” screen. Then select the checkbox “Open Edit Claim Rules” and click on Close.
8. Click on “Add Rule” button. Select template value as “Send LDAP attributes as claims”. Click Next to continue.
9. On configure Rule window, provide the name for rule as “Send AD Attributes”. Select the attribute store as “Active Directory”. In mapping table, add values as shown below and click Finish afterwards –
10. Click on “Add Rule” button again. Select the option as “Transform an incoming claim” and click Next to continue.
11. Provide the name of the rule as “Map Email to Name ID”. Select Incoming claim type as E-Mail Address, Outgoing claim type as Name ID, Outgoing Name Id format as Email. Select the radio button option as “Pass through all claims values”. Then click on Finish and OK on add claim rules main window to finish the procedure of adding claim rules.
As you can see, we added only Email address for AD attributes. Similarly you can add Name, Given Name and other attributes. The only thing you have to make sure that the Name ID is added as Transform claim only and it should not be added as AD attribute. This was not the case in Part 3 where we had added Name Id in AD attributes and Pass through transform claims where application was running locally.
12. Make sure that you have followed all the steps from 1 to 11 for both ADFS. In the case of this article, it is Antariksh.com and IndiaUniverse.com ADFS. The URL for IndiaUniverse.com domain will be https://multiadfssample.azurewebsites.net/Account/LoginCallbackIndiaUniverseAdfs.
This completes the change on ADFS side.
Application specific changes for Azure WebApp hosting
Let’s first observe the importance of the following line from startup.auth.cs class file –
BackchannelCertificateValidator = null,
This line of code is present for both of the Owin pipelines. The need for adding this line is to bypass the certificate chain validation for self-signed certificates. It should be present in the source code you have downloaded; if not, please add it. Also in Global.asax.cs file, we should have the following lines of code for certification chain validation bypass –
ServicePointManager.ServerCertificateValidationCallback = delegate
Please make sure that this line also is present else your code with self-signed certificates may not work.
If you observe Wreply and Wtrealm URL in Startup.Auth.cs class, they are still pointing to localhost URL. These need to be changed for Azure WebApp URL. So replace the part of URL https://localhost:44314/ with https://multiadfssample.azurewebsites.net/ in both pipelines or comment the localhost pipelines and add new. We need to add new URL and comment the localhost pipelines. Once done, the changed pipeline code blocks looks as shown below –
//configure Antariksh ADFS middleware
var antarikshADFS = new WsFederationAuthenticationOptions
MetadataAddress = "https://antariksh.cloudapp.net/FederationMetadata/2007-06/FederationMetadata.xml",
AuthenticationType = "Antariksh ADFS",
Caption = "Antariksh Domain",
BackchannelCertificateValidator = null,
//Wreply = "https://localhost:44314/Account/LoginCallbackAntarikshAdfs",
//Wtrealm = "https://localhost:44314/Account/LoginCallbackAntarikshAdfs"
//Azure Web Apps
Wreply = "https://multiadfssample.azurewebsites.net/Account/LoginCallbackAntarikshAdfs",
Wtrealm = "https://multiadfssample.azurewebsites.net/Account/LoginCallbackAntarikshAdfs"
//configure IndiaUniverse ADFS middleware
var indiaUniverseADFS = new WsFederationAuthenticationOptions
MetadataAddress = "https://indiauniverse.cloudapp.net/FederationMetadata/2007-06/FederationMetadata.xml",
AuthenticationType = "IndiaUniverse ADFS",
Caption = "India Universe Domain",
BackchannelCertificateValidator = null,
//Wreply = "https://localhost:44314/Account/LoginCallbackIndiaUniverseAdfs",
//Wtrealm = "https://localhost:44314/Account/LoginCallbackIndiaUniverseAdfs"
//Azure Web Apps
Wreply = "https://multiadfssample.azurewebsites.net/Account/LoginCallbackIndiaUniverseAdfs",
Wtrealm = "https://multiadfssample.azurewebsites.net/Account/LoginCallbackIndiaUniverseAdfs"
Build the solution from Visual studio. Here we have completed the changes required on application side.
After these changes, a new scenario of Azure WebApps integration with Azure VM based ADFS is as follows –
As you can see in above diagram, the MVC application is having trust relationship established with Antariksh and IndiaUniverse adfs by adding it as relying party and is hosted in Azure Web Apps. Similarly metadata URL of both ADFS is being used in Azure WebApps hosted MVC application. As we know, the URL of application https://multiadfssample.azurewebsites.net/ is the one by which ADFS knows to which application claims has to be sent. The same structure will be applicable in case of MVC application hosted in cloud service web roles.
Deploy application to Azure WebApp
I hope you have already downloaded the sample code given in Part 3 of this series. The overall solution in Visual Studio looks as below –
Now we just need to deploy this to Azure WebApps. Right click on ASP.NET MVC project and select Publish option as shown below –
You will see “Publish Web” dialog with various deployment options. Out of these options, click on “Microsoft Azure Web Apps” option as shown below –
Once you select “Microsoft Azure Web Apps”, another pop up appears asking for credentials. Click on “Sign In” button.
An additional pop up will open asking for Microsoft Account credentials. Enter the credentials. After entering correct credentials, the pop up may open and close automatically multiple times or may ask for credentials multiple times depending on your luck (pun intended). As of this writing, if you click on the “Sign In” button say 5-10 times, the pop up opened and asked me for credentials. Anyways after successful login all existing webapps will get listed. Select multiadfssample webapps from the dropdown and click OK to download the Azure WebApps publish settings files automatically.
Publish setting file gets automatically configured in publish dialog box. You can view all the details getting auto populated as below. The password gets auto generated and you don’t require to know it. Whenever you are publishing to the same web app again from the web app, the same password will be used from publish settings file. As you can see below, the server name is getting accessed over 443 port means entire publish operation will be performed over SSL and hence it is secure. Click on “Validate connection” button to confirm everything is good. A green checkmark will appear against “validate connection” button.
After this click on Next to continue. Next screen shows the configuration settings. Make sure you select the “Release” as configuration option. “File publish options” expansion widget is self-explanatory and for this deployment, I am going to keep the default unselected. We don’t have any DB dependency for this deployment so keep the default settings as it is. Click Next to continue.
On the next screen, click on “Start Preview” button. The system identifies all the new changes performed after last deployment. As this is our first deployment, all application files will be listed as changes.
Click on Publish to start the deployment to Azure webapps. Publish will be succeeded very quickly. Browse the URL - http://multiadfssample.azurewebsites.net/Account/Login. You can observe Antariksh.com and IndiaUniverse.com ADFs options appearing. Select “Antariksh ADFS” and pop up for asking credentials will appear. After entering the correct credentials, an error is thrown as below –
The error is thrown because we have added the web apps url as relying party as https and not http. Hence the error. So we need to make sure that we configure our web apps deployment over https. The SSL configuration can be done from Settings -> Custom domain and SSL option from azure new portal. However as you can see below, the SSL binding is available only for Basic or higher tiers whereas our current plan is Free. Plus we will need the certificate issued by valid CA (Certificate Authority) and it will require some investment.
But there is good news. By default Azure Web Apps works on https. Now this default https behavior is not secure. Because *.azurewebsites.net domain is Wildcard domain. I am going to take a couple of minutes here and urge you to read through the next important paragraph.
There are 3 kinds of certificates - Single domain, multi domain and wildcard. Single domain as the name indicates, is mapped to one domain – like kunal.com and others can’t share it. Multi domain means the same certificate will work for kunal.com and kunal2.com as well. Wildcard means you have certificate for parent domain and then all child domains can share the same. For example, if you create a free blogger site then all websites have blogspot.com common in them. For example, Kunal.blogspot.com, kunal2.blogspot.com and so on.
*.azurewebsites.net domain is equipped with such wildcard domain. So it is not secure. Therefore it is not recommended to use default https provision of Azure websites. You should create your own custom domain and then issue a certificate for that domain name. Although this domain is not production ready, but for Dev/test/demo scenarios, it is definitely useful. Moreover you don’t have to even use Self signed certificates for these wildcard domains. For our demo, we can definitely use the same.
Therefore instead of accessing http://multiadfssample.azurewebsites.net/Account/Login we will access it over https https://multiadfssample.azurewebsites.net/Account/Login. Log in to the application with Antariksh ADFS credentials and claims will be displayed as shown below –
Similarly claims will get displayed for IndiaUniverse.com domain as well. This completes the hosting of Owin Katana based application in Azure Web Apps.
Deploy application to Azure Cloud Service web role
Similar to Azure WebApps, we will host the ASP.NET MVC based application integrating with multiple ADFS using Owin Katana on another popular Azure PaaS hosting platform, know as Azure Cloud Services.
Create Cloud Service in Azure Portal
Click on New-> Compute -> Cloud Service as shown below –
Provide the name of cloud service as multiadfssample only. So the Url becomes https://multiadfssample.cloudapp.net/. Then select the same resource group we had created during WebApps provisioning. Select the location and subscription the same as Azure WebApps. Cloud service deployment requires an Azure Storage account. Therefore I already have one storage account created and will use the same as shown in the screenshot below –
This complete the cloud service creation.
Upload SSL certificate
The cloud service URL is by default http and does not work by default over https like Azure Web Apps. Now for ADFS authentication, we need relying party to be accessed over https therefore we will create a self-signed certificate and upload for the created cloud service.
To create self-signed certificate, choose Start > expand All Programs > expand Microsoft Visual Studio > Visual Studio Tools > Visual Studio Command Prompt developer tools. Alternatively you can even search for “Developer Command Prompt”. Then run the following command to have self-signed certificate generated.
makecert -sky exchange -r -n "CN=multiadfssample.cloudapp.net" -pe -a sha1 -len 2048 -ss My "multiadfssample.cloudapp.net.pfx"
Important – The name of certificate must be the same as your cloud service name.
The above command will install the certificate in the Personal store of current logged in user. Kindly export the .pfx from this certificate and install it in Local Machine -> Personal (or My) store. To perform this export, import etc. refer to the following link –
After export, upload the certificate to cloud service settings from the portal as shown below –
Convert source application to Cloud Service and Web Role project
Now to make the application deployed on cloud service as a web role, we need to make it compatible to Azure cloud service. Therefore as a first step, we will need to convert the ASP.NET MVC application to ASP.NET MVC web role application and add new cloud service type of project. The process is very simple. Click on Project “MultipleADFSDemo” and select the option “Convert to Microsoft Azure Cloud Service Project” as shown below –
This operation adds up the new cloud service project and also makes the current asp.net web application project as web role project as shown below –
Configure WebRole for https
Now we need to configure web role to be accessible over https using SSL certificate we generated earlier. Therefore right click on Web role name in cloud service project and select Properties.
In Properties window, select the Certificates option and click on “Add Certificate”. Select the option as Local Machine and My store and click ellipses button to open the local machine -> My store. Another pop up will open listing the certificate we created earlier. Select the certificate as multiadfssample.cloudapp.net and click Ok and Save.
Then select the Endpoints option and change the existing http endpoint to “https” endpoint along with “443” port and certificate as the one we added earlier from properties, as shown below –
This makes the web roles configured for https.
Configuration changes on ADFS
Now can you guess what changes will be required for ADFS for cloud service hosted application? You just need to add new relying party in both ADFS with respective cloud service URL. So please create relying party in both ADFs with the following URLs –
Then add the claim rules same as what we added for WebApps in above section and we are done here.
Application specific changes for Azure Cloud Service hosting
Again the changes required on application side are also similar. We just need to change the Wreply and Wtrealm URL. So comment the localhost and webapps related URL and add the following in the startup.auth.cs class –
For Antariksh -
//Azure cloud service
Wreply = "https://multiadfssample.cloudapp.net/Account/LoginCallbackAntarikshAdfs",
Wtrealm = "https://multiadfssample.cloudapp.net/Account/LoginCallbackAntarikshAdfs"
For IndiaUniverse –
//Azure cloud services
Wreply = "https://multiadfssample.cloudapp.net/Account/LoginCallbackIndiaUniverseAdfs",
Wtrealm = "https://multiadfssample.cloudapp.net/Account/LoginCallbackIndiaUniverseAdfs"
Now it’s time to publish the application to Azure Cloud Service.
Publish ASP.NET MVC application to Azure Cloud Service
Right click on cloud service type of project and select Publish option as shown below –
You may be asked to Sign in. Provide the correct credentials for Microsoft Account and then select the subscription of your choice and then click Next –
Select the cloud service as multiadfssample, Environment as Production, Build configuration as Release and Service configuration as Cloud. As of now, we don’t need the remote desktop access to the underlying VM of Azure Web Role, so no need to check the “enable Remote Desktop for all roles”. As remote desktop is not configured, the Web deploy checkbox next to it will remain disabled and it is absolutely fine.
Select “Advanced Settings” tab. Select the storage account of your choice and keep the rest of the settings as it is, and click Next to continue.
Next screen shows the summary which should be correct if you have selected above stated options. Click on Publish to start publishing to cloud service. Publish to cloud service will take around 15-20 minutes to complete the entire operation.
Why Azure Cloud service deployment is slower than Azure WebApps deployment
There is a very logical reason to why cloud service takes so much of time to complete the deployment, as compared to Azure WebApps. If you observe, in the publish window of cloud service, you will see some messages stating –
1. Creating the virtual machine
2. Starting the virtual machine
This indicates that Azure VM required for Web Role application deployment is not preconfigured, pre-created. New VM is allocated for our deployment and it is being configured from scratch. However in case of Web Apps, the VM’s are already present with all the prerequisites of running an application. So it is just a matter of copying the application files and binaries in case of Azure WebApps deployment. Hence WebApps deployment is faster as compared to cloud service deployment.
Once the deployment of cloud service is completed, then you can access the deployed application with URL - https://multiadfssample.cloudapp.net/. Login with credentials of respective ADFS and view the claims.
This completes the deployment of application to Azure Cloud Service.
In this part of Identity and Azure series we saw that how an ASP.NET MVC application integrated with multiple ADFS using Owin Katana can be hosted in either Azure WebApps or Azure Cloud Service.
So far we have worked hard to integrate multiple ADFS as explained in Part 3 and our current article. However if you are ready to pay some extra bucks, then you can use 3rd Party (Paid) Identity Server Provider like Auth0 to achieve multiple WSFederation (or ADFS) authentication in ASP.NET MVC application. This will be the last article of this series. Stay tuned!