17 Comments

Since the initial release of the Windows Azure Management Libraries (WAML) as Portable Class Libraries (PCL, or pickles as I like to call them) we’ve had tons of questions from community members like Patriek asking how Windows Phone applications can be written that make use of the cloud management functionality WAML offers. At first glance it would seem that WAML is “unsupported on Windows Phone,” but the reality is that WAML is fully supported via it being a PCL, but some external factors made it seem just shy of impossible to be able to glue our PCL framework to each of the targeted client platforms. In the case of Phone, there are two blockers:

  1. Since the X509Certificate2 class is unsupported on Windows Phone developers can’t make use of the certificate-based method of authenticating against the Azure REST API
  2. Since there’s no ADAL implementation that targets Phone there’s no way to use ADAL’s slick functionality to get my authentication token. The assumption here is that some creative coding is going to have to be done to go deeper into the OAuth stack. Sounds nasty.

Well, that’s never stopped any motivated coder before, right? Armed with some code from Patriek, a problem statement, and a pretty informative blog post written by none other than Vittorio on how he had some fun tying Phone to REST Services using AAD, I set out to start at ground zero to get some code working on my phone that would enable me to see what’s happening in my Azure subscription, across all my sites, services, and data stores. I set out to create a new type of phone app that will give me complete control over everything I’ve got published to my Azure cloud subscription. This post will walk through the code I worked up to get a baseline Windows Phone mobile cloud management app running.

Creating and Configuring the Phone App

First, a little background is required here. As Vittorio’s post makes very clear, the OAuth dance the WP8 code is going to be doing is pretty interesting, challenging, and results with a great set of functionality and an even greater starting point if this app gives you some ideas on what you could make it do next. In fact, if you’re into that whole social coding thing, the code in this post has a GitHub repository right here. The code in the repository contains the project I created in this screen shot in more detail.

01

The first step is to pull down the NuGet pacakges I’ll need to write this application. In this particular case I’m kind of thinking of writing a Windows Phone app that I’ll use to management my Azure Web Sites, Cloud Services, SQL Databases, Storage Accounts, and everything in between. So I’ll right-click my Phone project and select the correct packages in next step.

02

I’ll go ahead and pull down the entire WAML NuGet set, so I can manage and view all of my asset types throughout the my Azure platform subscription. By selecting the Microsoft.Windows Azure.Management.Libraries package, all of the SDK Common and WAML platform NuGets will all be pulled down for this application to use.

03

The Common SDK, shown below in the project’s references window, provides the baseline HTTP, Parsing, and Tracing functionality that all the higher-order WAML components need to function. Next to that is the newest member of the Common SDK tools, the Common Windows Phone reference, which is new in the latest release of the Common SDK package. This new addition provides the high-level functionality for taking token credentials from within the Windows Phone client and being able to attach those credentials to the SDK client code so that calls made to the Azure REST API from a phone are authenticated properly.

04

If you read my last blog post on using WAAD and WAML together to authenticate WAML-based client applications, there are a few important steps in that post about working through the process of adding an application that can authenticate on behalf of your WAAD tenant. Take a look at that post here to get the values for the App Resources dialog in the screen shot below. In a sense, you’ll be setting application settings here that you can get from the Azure portal. You’ll need to create an application, then get that app’s client id, and your subscription and active directory tenant id or domain name, and place those values into the code’s resources file, as shown below.

06

The Login View

The first view shows a built-in web browser control. This web browser will be used to direct the user to the login page. From there, the browser’s behavior and events will be intercepted. The authentication data the form contains will then be used to manually authenticate the application directly to AAD.

Reminder – As Vittorio’s post pointed out, you might not want to use this exact code in your production app. This is a prototype to demonstrate putting it all together in the lack of important resources. Something better will come along soon. For now the OAuth dance is sort of up to me.

Note the web browser control has already been event-bound to a method named webBrowser_Navigating, so each time the browser tries to make a request this method handler will run first, and allow my code to intercept the response coming back to the browser.

05

Once the login page loads up, I’ll presume a login is in order, so I’ll go ahead and navigate to the login page, passing in a few of my own configuration parameters to make sure I’m hitting my own AAD tenant.

07

Vittorio deep-dives on the workflow of this code a lot better than I’ll try to do here. The basic idea is that the browser flow is being intercepted. Once the code realizes that AAD has authenticated me it hands back a URL beginning with the string I set for the redirectUrl property of this application in the portal. When my code sees my redirectUrl come through, I just run the GetToken() method to perform the authentication. It posts some data over the wire again, and this time, the response activity is handled by the RetrieveTokenEndpointResponse() event handler.

08

Once this handler wakes up to process the HTTP response I’ve received from the AAD authentication workflow (that we did via the OAuth dance), my access token is pulled out of the response. The subscription id value is then persisted via one of my App’s properties, and the next view in the application is shown.

09

When the user first opens the app, the obvious first step is visible. We need to show the user the AAD login site, and allow the user to manually enter in their email address and password. In this window. I could use a Microsoft (Live/Hotmail/etc.) account or an organizational account. The latter, so long as they’ve been marked as Azure subscription co-admins, would be able to log in and make changes, too.

16

Once the user logs in they’ll be shown a list of their subscriptions, so let’s take a look at how the code in the subscriptions view is constructed.

Selecting a Subscription

The subscription selection view just shows a list of subscriptions to the user in a long scrolling list. This list is data-bound to the results of a REST API call made via the SubscriptionClient class, which goes out and gets the list of subscriptions a user can view.

Note – even though I can see my full list of subscriptions, I’ve only installed the Application into one AAD tenant in one of my subscriptions. If I click any of the other subscriptions, things won’t work so well. A subscription and a tenant are tied together. Unless your application gets special permission (it does happen from time to time, I hear) your application can only access Azure assets in the same subscription. If you wanted to work across subscription you’d have a little more work to do.

The XAML code below shows how the list of subscriptions will be data-bound to the view. I may eventually go into this code and add some view/hide logic that would show only those subscriptions I could impact using the application settings I’ve got running in this app. Point is, I can see all of the subscriptions I can manage and conceptually manage them with some additional coding.

10

The code below is what executes to log a user in with their stored access token and subscription id, when the TokenCloudCredentials class is used to wrap their credentials up as a single construction parameter to most of the management client. Since I was able to get a token from the OAuth dance with AAD, and since I know which subscription ID I want to affect, I’ve got everything I need to start working against the rest of the service management REST API endpoints.

11

When the subscriptions page loads, it gives me the chance to select the subscription I want to manage. Note: I just need to be cautious and only click the subscription that matches the subscription where my AAD tenant is set up. In my case, I’ve got the application installed into my AAD tenant that lives in the subscription named Windows Azure MSDN – Visual Studio Ultimate. If I were to select any of my other subscriptions I’d get an exception.

To have true parity across all subscriptions you’d need to have an application setup in each of your directories and some additional configuration, or you’d have to allow other tenants set up multi-tenancy with your AAD tenant.

17

Once the subscription list is data-bound the user can select a subscription to work with. Selection of a subscription item in the list fires the following code.

12

It persists the subscription id of the subscription the user selected, and then navigates the user to the AssetListView page, which will show more details on what’s in a user’s Azure subscription.

Viewing Cloud Assets via Mobile Phone

To provide a simple method of being able to scroll through various asset types rather than emulate the Azure portal, I made use of the LongListSelector and Pivot controls. In each Pivot I display the type of Azure asset being represented by that face of the pivot control. Web Sites, slide, Storage, slide, SQL, slide, Cloud Services… and so on. The idea for the phone prototype was to show how WAML could be used to load ViewModel classes that would then be shown in a series of views to make it easy to get right to a particular asset in your Azure architecture to see details about it in a native Phone interface.

13

Since the assets list page is primarily just a logically-grouped series of lists for each of the types of assets one can own in their Azure stack, the ViewModel class’s main purpose is to expose everything that will be needed on the view. It exposes Observable Collections of each type of Azure asset the app can display.

14

What would be better as controller functionality, the code in the codebehind of the view ends up doing most of the data-acquisition from the Azure REST APIs via WAML calls. In the code sample below the GetWebSites method is highlighted, but the others – GetSqlDatabases, GetStorageAccounts, and GetHostedServices – all do the same sorts of things. Each method creates instances of appropriate management client classes, retrieves asset lists, and data-binds the lists so that the assets are all visible in the Windows Phone client.

15

The web sites pivot is shown below. I’m thinking of adding a deeper screen here, one that would show site statistics over the last N days, maybe add an appSetting and connectionString editor page, or something else. Have any ideas?

18

Here’s a list of my cloud services – 2 empty PaaS instances and 1 newly set-up VM instance.

19

Summary

Though the OAuth dance has a few drawbacks and the code is a little less elegant than when I could make use of ADAL in my previous example, it works. Once I have the token information I need from the browser, I can run with that information by creating an instance of a TokenCloudCredential, passing in the token I received from the OAuth dance to get to authenticate WAML and therefore, make calls out to the Azure Service Management API to automate my asset management. Since WAML is a PCL package, and as a result of the introduction of support for the Windows Phone platform into the SDK Common NuGet package, the community can now freely experiment with solutions combining Windows Phone and the Management Libraries.

Happy Coding!

Comments

Comment by Patriek

Awesome! Now I realize that my problem was just due to the fact that I didn't select the right subscription. If I'd just selected the subscription my AAD tenant was in, it would have worked.

I'll dive into this whole multi-tenancy thing later this week to figure out how I can manage multiple subscriptions.

Thanks for this information.

Comment by Tjeerd-menno

Great!

My Remote VM Manager WP8 project had been on hold while I was waiting for a solution to the not being able to use X509certificates issue.

Tjeerd-menno
Comment by brady gaster

Patriek, that also bit me and I worked for a few hours to figure out which tenant subscription would work. I think having multiple tenants in a subscription made it a little more confusing for sure. :)

Tjeerd - hope this post unblocks your project. I'd love to see some code once you get it up and running!

brady gaster
Comment by Jamy Ryals

Awesome start - I could really use something like this to manage our subscriptions. Cloning your repo now.

Jamy Ryals
Comment by Arri

Nice to see you got something working! You helped me out at the build hackathon last year when I made a failed attempt at this. Whole idea fell apart once I couldn't find a work around for the X509 limitation.

Arri
Comment by Ricky

Hi,

I've downloaded your code from github and retrieved my Client ID, tenant ID and my redirect URL from your previous tutorial. The app logs me in and shows me a list of my subscription but when I select my subscription the code fails and returns this exception
"AuthenticationFailed: A security token exception occured for the received JWT token."

at "var webSpaceListResult = await webSiteClient.WebSpaces.ListAsync();"
in AssetListView.xaml.cs.

Can you help me out in resolving this exception? I looked around the internet but couldn't find anything useful. Any help would be greatly appreciated,

Thanks.

Ricky
Comment by brady gaster

Ricky - did you make *absolutely sure* that you enabled access to the Azure API in your application? If you did, use the SubscriptionClient to pull your list of subscriptions. Check to see if the ActiveDirectoryTenantId property of the subscription you want to "tweak" matches the tenant id you have in your code.

Also, did you create a second directory or use the default. If you didn't use the default, try that, too.

Please let me know what you uncover on this, too. ADAL/MAML is an important story and if you're having issues with it I want to work with Vittorio to get it right for you and the rest of the community.

brady gaster
Comment by dirksmith

Hi,
I got the same error : "AuthenticationFailed: A security token exception occured for the received JWT token."
during call to method.
var createHostedServiceResult = await computeManagementClient.HostedServices.CreateAsync(
new HostedServiceCreateParameters
{
Label = "mydemocreatevm",
Location = LocationNames.SoutheastAsia,
ServiceName = randomName
});

Strange thing is I got the subscription list using subscription client but its not working for comouteclient.
Please help on this.

dirksmith
Comment by Gábor Domonkos

I also tried to run the sample code with the right credentials (tried with 3 AAD) without success.
Maybe something changed in the NuGet or at the Portal so we have to change something in the application? I can get the list of subscriptions
The error message is the same:

AuthenticationFailed: A security token exception occured for the received JWT token.

at this line:

var webSpaceListResult = await webSiteClient.WebSpaces.ListAsync();

Thank you very much!

Gábor Domonkos
Comment by nzpcmad

OK - I'm confused.

"Since there’s no ADAL implementation that targets Phone ..."

But according to:

http://www.cloudidentity.com/blog/2014/09/04/active-directory-authentication-library-adal-v2-for-netwindows-storewindows-phonegeneral-availability/ :

"Today it is my honor and privilege to announce the general availability of ADAL v2 for .NET, Windows Store and Windows Phone apps!"

Comment by ponsakthi

Hey guys!!! I am also getting the same error.
I was not able to get the list of CloudServices from the Service Management API.
Did any one resolve this issue?

ponsakthi
Comment by Prashant

Hello Brady,

I am getting error in RetrieveTokenEndpointResponse() method on second line (HttpWebResponse resp = hwr.EndGetResponse(rez) as HttpWebResponse;)

Then i debug my application and checked WebBrowser_Navigating() function.

When i check this line if (returnURL.StartsWith(AppResources.AAD_REDIRECT_URL)),
my returnURL consists of below URL

http://localhost/wamlphone?error=access_denied

Prashant
Comment by brady gaster

nzpcmad - that post came out after mine on this topic. :)

Comment by brady gaster

Is the "wamlphone" the name of your AAD application? Or is some of my old code hanging around in there with an "accidental constant?"

Comment by Prashant

wamphone is the code you have written.
and i have set is as AAD_REDIRECT_URL http://localhost/wamlphone .
and also as my REDIRECT URL in AAD Application

Prashant
Comment by Prashant

The error i am getting is
http://localhost/wamlphone?error=access_denied

Prashant
Comment by Prashant

The error i am getting is http://localhost/wamlphone?error=access_denied

Prashant
Post comment