Thursday, November 6, 2014

Authentication with third party Auth providers in new era of Mobile Apps

When you are developing app, to increase security and manipulate users without taking user details is use authentication providers help such like Live, Google, Facebook, twitter , linked in, flickers etc.

With the newer versions of mobile BCL is not supported the olde way of authenticating with third party SDK's. All the BCL are updated with 8.1 and Universal apps.

With this post I'm gonna explain how to implement those authentication (ex: facebook)

1. you need to have facebook app. (http:\\developer.facebook.com)

To implement the Authentication you need to create separate class and interface that can handle Continuation events. Once authentication done it will redirect to the app using these Continuation objects.

Here is ContinuationManager Class that I used

using System.Text;
using Windows.ApplicationModel.Activation;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
 
#if WINDOWS_PHONE_APP
    /// <summary>
    /// ContinuationManager is used to detect if the most recent activation was due
    /// to a continuation such as the FileOpenPicker or WebAuthenticationBroker
    /// </summary>
    public class ContinuationManager
    {
        IContinuationActivatedEventArgs args = null;
        bool handled = false;
        Guid id = Guid.Empty;
 
        /// <summary>
        /// Sets the ContinuationArgs for this instance. Using default Frame of current Window
        /// Should be called by the main activation handling code in App.xaml.cs
        /// </summary>
        /// <param name="args">The activation args</param>
        internal void Continue(IContinuationActivatedEventArgs args)
        {
            Continue(args, Window.Current.Content as Frame);
        }
 
        /// <summary>
        /// Sets the ContinuationArgs for this instance. Should be called by the main activation
        /// handling code in App.xaml.cs
        /// </summary>
        /// <param name="args">The activation args</param>
        /// <param name="rootFrame">The frame control that contains the current page</param>
        internal void Continue(IContinuationActivatedEventArgs args, Frame rootFrame)
        {
            if (args == null)
                throw new ArgumentNullException("args");
 
            if (this.args != null && !handled)
                throw new InvalidOperationException("Can't set args more than once");
 
            this.args = args;
            this.handled = false;
            this.id = Guid.NewGuid();
 
            if (rootFrame == null)
                return;
 
            switch (args.Kind)
            {
               
 
                case ActivationKind.WebAuthenticationBrokerContinuation:
                    var wabPage = rootFrame.Content as IWebAuthenticationContinuable;
                    if (wabPage != null)
                    {
                        wabPage.ContinueWebAuthentication(args as WebAuthenticationBrokerContinuationEventArgs);
                    }
                    break;
            }
        }
 
        /// <summary>
        /// Marks the contination data as 'stale', meaning that it is probably no longer of
        /// any use. Called when the app is suspended (to ensure future activations don't appear
        /// to be for the same continuation) and whenever the continuation data is retrieved 
        /// (so that it isn't retrieved on subsequent navigations)
        /// </summary>
        internal void MarkAsStale()
        {
            this.handled = true;
        }
 
        /// <summary>
        /// Retrieves the continuation args, if they have not already been retrieved, and 
        /// prevents further retrieval via this property (to avoid accidentla double-usage)
        /// </summary>
        public IContinuationActivatedEventArgs ContinuationArgs
        {
            get
            {
                if (handled)
                    return null;
                MarkAsStale();
                return args;
            }
        }
 
        /// <summary>
        /// Unique identifier for this particular continuation. Most useful for components that 
        /// retrieve the continuation data via <see cref="GetContinuationArgs"/> and need
        /// to perform their own replay check
        /// </summary>
        public Guid Id { get { return id; } }
 
        /// <summary>
        /// Retrieves the continuation args, optionally retrieving them even if they have already
        /// been retrieved
        /// </summary>
        /// <param name="includeStaleArgs">Set to true to return args even if they have previously been returned</param>
        /// <returns>The continuation args, or null if there aren't any</returns>
        public IContinuationActivatedEventArgs GetContinuationArgs(bool includeStaleArgs)
        {
            if (!includeStaleArgs && handled)
                return null;
            MarkAsStale();
            return args;
        }
    }
 
    /// <summary>
    /// Implement this interface if your page invokes the web authentication
    /// broker
    /// </summary>
    interface IWebAuthenticationContinuable
    {
        /// <summary>
        /// This method is invoked when the web authentication broker returns
        /// with the authentication result
        /// </summary>
        /// <param name="args">Activated event args object that contains returned authentication token</param>
        void ContinueWebAuthentication(WebAuthenticationBrokerContinuationEventArgs args);
    }

To handle the continuation after authentication you nee to modify your app.xaml.cs as well. Because Once you redirect to auth providers screen you are exit (deactivate) your app. then once auth provider redirect back your app gets activate .

Create object of ContinuationManager  in App.xml.cs

public static ContinuationManager continuationManager { getprivate set; }

Then OnActivated event of the app add the continuation handle

protected async override void OnActivated(IActivatedEventArgs e)
{
   continuationManager = new ContinuationManager();
 
   //Check if this is a continuation 
   var continuationEventArgs = e as IContinuationActivatedEventArgs;
   if (continuationEventArgs != null)
   {
	continuationManager.Continue(continuationEventArgs);
   }
 
  Window.Current.Activate(); 
}



Then you are free to go with any kind of authentication that provide from auth provider 

    internal async Task FacebookLoginMethod()
        {
            String FacebookURL = "https://www.facebook.com/dialog/oauth?client_id=" + Uri.EscapeDataString("Your app Id") + "&redirect_uri=" + Uri.EscapeDataString("https://m.facebook.com/dialog/return/ms") + "&scope=read_stream&display=popup&response_type=token";
 
            System.Uri StartUri = new Uri(FacebookURL);
//To use windows phone or windows app with Fb authentication user this end uri and redirect uri. Both are working 
             System.Uri EndUri = new Uri("https://m.facebook.com/dialog/return/ms");
 
#if WINDOWS_PHONE_APP
            try
            {
                WebAuthenticationBroker.AuthenticateAndContinue(StartUri, EndUri, null, WebAuthenticationOptions.None);
            }
            catch
            {
 
            }
#endif
        }


and use this ContinueWeb authentication method inside the page that you call authentication. otherwise it will not working. Inherit the IWebAuthnticationContinuable interface to the page and add this method

public async void ContinueWebAuthentication(WebAuthenticationBrokerContinuationEventArgs args)
       {
           WebAuthenticationResult result = args.WebAuthenticationResult;
           if (result.ResponseStatus == WebAuthenticationStatus.Success)
           {
               token = await FilterToken(result.ResponseData.ToString());
 
           }
           else
           {
               MessageDialog Msg = new MessageDialog("Login failed");
               Msg.ShowAsync();
           }
 
       }


This WebAuthentication result wil contains the Authprovider's access token. Filterout it and do what ever graph is available with authentication provider. 


Enjoy ..








0 comments: