Windows 8 Metro Applications and the Azure (Cont.)

As I mentioned before, I am going to write the last post about integrating Windows 8 Metro applications with Azure.

First of, let’s take a look at securing our service with Forms Authentication.  I blogged about that as well, and the only change is that I am going to use REST for authentication service.  Here is the interface for my service – it is very simple:

    [ServiceContract]
    public interface ILoginService
    {
        [OperationContract]
        [WebGet(UriTemplate = "/Login/?userName={userName}&password={password}", 
            RequestFormat = WebMessageFormat.Json, 
            ResponseFormat = WebMessageFormat.Json)]
        bool Login(string userName, string password);

The implementation is using Users table I mentioned before:

    [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Required)]
    public class LoginService : ILoginService
    {
        public bool Login(string userName, string password)
        {
            bool returnValue = false;
            using (var context = new QuotesContext())
            {
                var user = context.Users.FirstOrDefault(one => one.UserName == userName);

                if (user != null)
                {
                    returnValue = (user.Password == password);
                }
            }
            if (returnValue)
            {
                var ticket =
                    new FormsAuthenticationTicket(
                        1,
                        userName,
                        DateTime.Now,
                        DateTime.Now.AddHours(24),
                        false,
                        "",
                        FormsAuthentication.FormsCookiePath);

                string encryptedTicket = FormsAuthentication.Encrypt(ticket);
                var cookie = new HttpCookie(FormsAuthentication.FormsCookieName, encryptedTicket)
                {
                    Path = FormsAuthentication.FormsCookiePath,
                    Expires = DateTime.Now.AddHours(24)
                };

                HttpContext.Current.Response.Cookies.Add(cookie);
            }
            return returnValue;
        }

The code is pretty straight forward as you can see.  Just match user name and password and create authentication cookie to be passed back to the client.

Now on Windows 8 side the code is just as easy, I am just going to use HttpClient class:

var client = new System.Net.Http.HttpClient();
 
            var responce = await client.GetAsync(new Uri("http://xxxx.cloudapp.net/LoginService.svc/Login/?userName=admin@system.com&password=_Random1"));
            var text = await responce.Content.ReadAsStringAsync();
            if (text.ToLower().Equals("true"))
            {
                responce = await client.GetAsync(new Uri("http://xxxxx.cloudapp.net/QuoteService.svc/GetQuote"));
                text = await responce.Content.ReadAsStringAsync();
                if (text.LastIndexOf("-") >= 0)
                {
                    text = text.Substring(0, text.Replace("--", "-").LastIndexOf("-")) + Environment.NewLine + text.Substring(text.Replace("--", "-").LastIndexOf("-"));
                }
                text = text.Replace("  ", " ");
                if (text.StartsWith("""))
                {
                    text = text.Substring(1);
                }
                if (text.EndsWith("""))
                {
                    text = text.Substring(0, text.Length - 1);
                }
                QuoteBlock.Text = text.Trim();
                quoteGrid.Visibility = Windows.UI.Xaml.Visibility.Visible;
            }

Getting the data from protected service is a two step process.  I am first calling authentication service, passing user and password as query string parameters, then I verify that authentication was successful, then I call the real service using the same instance of the HttpClient, which will pass my authentication cookie.  The rest of the code just deal with return value processing.

As far as updating the tile, the story is less bright in my opinion.  According to Microsoft there is not way to secure the end point that tile updater will call.  So, I cannot do what I wanted to.  Not only that, but processing XML that file updater expects does not work properly when you create it from XDcoument.  So, here is the solution I came up with.  I am going to simply create a text file with a placeholder for the actual content, then write worker role that would get the content, then update the XML, then upload it to Azure Blob Storage.  Then I can retrieve very simply by calling

PeriodicUpdateRecurrence recurrence = PeriodicUpdateRecurrence.HalfHour;
 
System.Uri url = new Uri("http://xxxx.blob.core.windows.net/quotes/quote?sr=b&si=Random&sig=VUErCXWGIczO9pLLNI4nc4m2DTTixUg%2F9%2F2qYqY1BAY%3D");
 
TileUpdateManager.CreateTileUpdaterForApplication().StartPeriodicUpdate(url, recurrence);

You can use for example  https://www.myazurestorage.com/ to create a blob container and set access policy on it as well as create a URL to a specific blob entry.  That is what I did, and you can see my policy called Random as part of the URL above.  There is also no easy way to troubleshoot the process if you get any steps wrong.  Here is an example tile XML you can just upload to blob storage for testing.  I know it works.

<tile>
  <visual lang=”en-US”>
    <binding template=”TileWideText03″>
      <text id=”1″>Testing 123…</text>
    </binding> 
  </visual>
</tile>

Enjoy.

One Comment

  1. Pingback: Windows 8 Metro Applications and the Azure « Sergey Barskiy's Blog

Leave a Reply

Your email address will not be published. Required fields are marked *