In the first two days of my 30 days, I set up my Azure App Service environment – both for local development and cloud deployment. I now have a deployable package and am able to edit the files locally. I’ve also got a modified Apache Cordova application and I’ve deployed that to Ripple – a Cordova emulator that runs in the Chrome browser.
Now, let’s move onto authentication. Azure App Service provides in-built support for five different authentication schemes – Facebook, Twitter, Google and Microsoft Account authentication schemes are all considered “social authentication”. Azure AD, on the other hand, is “enterprise authentication”. In addition, you can use the in-built support with either a server-flow (where the service do all the redirects for you in a web-based flow), or client-flow (where you use the client SDK for the identity provider to obtain a token and then swap the token for one that can be used with App Service). If that wasn’t enough, you can eschew the App Service authentication scheme altogther and roll your own with custom authentication. Over the next few blog posts I’m going to take a look at each of these – starting today with a server-based flow.
I find that Azure AD is more complicated than the social authentication providers. With social authentication providers, you use the social provider to set up the OAuth 2.0 flow, get the client ID and secret from the social provider, plug those into the Azure App Service Authentication / Authorization area, and it’s pretty much good to go. There is really good tutorial on this on the Azure Website for each client device.
Azure AD authentication takes a little bit more understanding. You have to set up Azure AD (which most mobile / casual developers don’t have), set up a client, link it into the App Service, then do the client changes. In addition, having Apache Cordova as my client is also complicating things – there are things to understand on this topic as well. So that’s todays task – get an Apache Cordova mobile app working within the Ripple emulator and authenticating to an Azure AD directory.
Step 1: Set up an Azure AD directory
Let’s start with some information about Azure AD. You want a tenant. From the documentation:
In Azure Active Directory (Azure AD), a tenant is representative of an organization. It is a dedicated instance of the Azure AD service that an organization receives and owns when it signs up for a Microsoft cloud service such as Azure, Microsoft Intune, or Office 365. Each Azure AD tenant is distinct and separate from other Azure AD tenants.
Here is the good news. You already have a tenant. In the Azure Portal sidebar, click on Browse> – Active Directory is right at the top. Of course, in a developer subscription, this will not be connected to your enterprise Active Directory instance. It’s standalone. You can create a new directory in the Classic Portal (Click on the big NEW button at the bottom – Active Directory is located under the App Services section). However, I’m going to use my Default Directory for this demo. I have created a new test account – this is a standalone account I’m going to use. To do that, click on ADD USER at the bottom of the page:
Fill in the account information. Note that you can add information from other tenants – including partner organizations. This is interesting for a number of situations. For example, let’s say you were creating an enterprise mobile app that allowed your customers and employees to interact somehow. You can create a new tenant for the app, then add the employees involved so they can log in. Finally, you can have a sign-up process that adds social accounts to the Azure AD tenant for your customers.
The next page allows you to add information:
Sorry – I’m not going to cover multi-factor authentication here. That’s a subject for Azure AD. Note that if you do set it up properly, then the multi-factor authentication will work with your mobile application.
Finally, click on the big green button to create the account and get the temporary password. Make a note of the password – we’ll need it later on before closing out the wizard.
Step 2: Configure Azure App Service
There is a complicated way of configuring Azure App Service to use your Azure AD and a simple way. I like simple. Find your Azure App Service, go into Settings then Authentication / Authorization.
Turn authentication on, then use the dropdown underneath the toggle to select Allow Request (no action). This is important for a couple of reasons. Firstly, it allows you to control which endpoints need to have authentication and which ones can be accessed anonymously. Secondly, it allows anonymous access features like Swagger UI to continue working. More on Swagger UI in a later article. If you select a specific provider in that dropdown, all requests will cause a 401 Unauthenticated if you have not authenticated – even the ones you specify as anonymous in your application.
Once you have made those two changes, click on Azure Active Directory to start the configuration process. There is an Express mode and an Advanced mode. The simple / quick mode is Express, so select that.
Just leave the rest of it alone. Click OK. It will create a new application ID for you, configure Azure AD and then configure the App Service for you. On the way out, click on Save to save your settings.
Testing the connection is simple. Open up a browser and point your browser at https://yoursite.azurewebsites.net/.auth/login/aad – this is the endpoint that initiates a login request. Do this in a private browsing session:
Note the differing form for the username – this is the “email address” of the test user I created. I used the temporary password that I got given. I’ll have to go through a one-time change-password process. Once that is done, I’ll get a nice banner saying I was successful.
Note that I’ve not altered the backend code and I won’t be telling the client about the specific Azure AD environment either. That means you can use a test Azure AD tenant for development and move it over to your enterprise production Azure AD tenant when it’s time to go live – without changing any code.
This nice banner is my signal that I’ve set things up properly.
Step 3: Update Apache Cordova to log in
I have a small confession to make at this point. I wanted to go through this entire series without touching my PC. Mac all the way! Why? Because I’ve learned that mobile developers love their macs. I’m honestly not sure why. Developing Apache Cordova apps and using all the facilities that I’ve grown accustomed to within the PC ecosystem – including Visual Studio, Ripple, and
so on – makes developing on a mac painful. I did the development on a PC in
Visual Studio, checked in the code to GitHub and then transferred it to the
mac.
You can get the initial source code from my GitHub Repository at tag day-3-pre.
You may be wondering what the difference is between this project and the regular Zumo Quickstart. Simply put, you have to click a button to get into the app. This becomes very important shortly, because we are going to add a login screen. Before you continue, make sure you can run this project in Ripple. In Visual Studio, this is very easy – just select Ripple (any of the device profiles will do) from the Run… drop-down, and click the Ripple button. On a mac, assuming you’ve got everything set up properly, run ripple emulate.
Adding login code to the Apache Cordova project is easy. Let’s adjust things so that the login button calls the ZUMO login. The code is in the www/js/index.js file:
Before you run this in Ripple, run this in the Android Emulator. When you click on the button, you will be taken to the same AAD screen flow that you saw when you were testing the AAD setup. It will be slow, but it should work. Now, close that down and start the project in Ripple again and go through the same process.
Firstly, you will notice that Ripple is not REALLY Cordova. It’s really just a locally hosted web service. That has some profound implications for your app. All of a sudden, you have to worry about Cross-Origin Resource Sharing (CORS) – something you don’t need to worry about on a real device. You go through the same flow, but when you get to the end, you get a blank browser window and no amount of teasing will progress you further. You’ve run into an issue that isn’t unique to Ripple or Cordova. Rather it is unique to browser environments where the pages are not being served from the same location as the authentication service. It’s akin to CORS (but not a CORS issue).
You won’t bump into this problem anywhere else EXCEPT Apache Cordova in hosted environments (as opposed to real or emulated devices). You only need to deal with this issue during development on locally running services.
Step 4: Fix the Ripple Issues
To fix this issue, you need to do some more configuration on the App Service. Basically, you need to tell it about your local development environment. First off, let’s look at the Ripple screen:
Note the proxy port there. This is for Ripple. Ripple runs on http://localhost:4400. If you were doing a web service and using a node backend, it may be running on http://localhost:3000, as port 3000 seems like the port to use. If you were using Ionic Live Reload, that lives on http://localhost:8100 by default. Of course, you can change all these numbers, but you will likely know what you have changed them to.
Log onto the Azure Portal and go to your App Service, then All Settings, then CORS (which is under the API menu – you will need to scroll down a bit):
Enter the URL for your service in the box provided and click on OK. I’m using Ripple, so that’s http://localhost:4400:
Don’t forget to click on Save, then close the blade. Adding to the CORS list isn’t enough though – you also need to add the local service to the External Redirect URIs list. That’s a little more complex.
Go back to your main app page, then click on Tools and select Resource Explorer.
Click on Go to launch the resource explorer tool in another tab or window. Expand the config node for your site and click on authSettings:
This will show you a JSON configuration settings sheet for the authentication blade. The blade provides a UI for managing this, but there is one setting that isn’t managed through the UI – the allowedExternalRedirectURIs – we need to change this:
Normally, this view is read-only. That’s because you can really screw up your site if you get this wrong. Click on the Read/Write toggle at the top of the screen. That still doesn’t get you in an edit mode, though. So next, click on the Edit button – this will turn into a Cancel button. Finally, you can click into line 14 and make some changes. In this case, I’ve turned the default null into a JSON array with my local development service for Ripple listed. Triple-check that you haven’t made any mistakes before proceeding. When you are sure, click on Put at the top to patch your configuration. You will get a saving spinner and then the changes will be made and the auth service for your site will be restarted. It takes about 10-15 seconds for the restart to be effective.
I recommend closing the Resource Explorer or going back into Read-only mode after you have made the change.
When you test the app within Ripple, it should pop up the same big window, walk you through the process of signing on, and then the authentication window will close and your app will continue on to the actual Todo app list.
Next Steps
There is a lot more to be said on the topic of authentication. We’ve explored just one side of authentication – the server-flow – and talked about some of the pitfalls of developing with Apache Cordova in this case. In the next article, I’ll convert this application to a client-flow to show the difference there.
If you want the final code for this day, you can find it on my GitHub Repository.
Filed under: Mobile Development Tagged: apache-cordova, azure, azure-ad, azure-mobile