Главная
Блог разработчиков phpBB
 
+ 17 предустановленных модов
+ SEO-оптимизация форума
+ авторизация через соц. сети
+ защита от спама

Используем внешнюю аутентификацию Windows Azure Mobile Services в десктопном WPF приложении

Anna | 17.06.2014 | нет комментариев
Здравствуйте!

Одной из комфортных функций Windows Azure Mobile Services является применения внешних служб аутентификаций, которые предоставляются Google, Facebook, Twitter и сам Microsoft Account. Это обозначает, что разработчику, нет необходимости имплементировать работу с всяким из них отдельно, для этого есть унифицированные способы.

Среди официально поддерживаемых платформ числится примерно все кроме… традиционной Windows Desktop.

О чём речь

В официальной документации по аутентификации достаточно аналогично расписан способ применения этого функционала, впрочем, приведённый в нём примеру завязан на платформозависимый Windows.UI.Popups. Неужто такая мелочь может удержать нас от применения этого сильного инструмента в разработке для привычной среды, которая к тому же, все ещё главенствует? Давайте разбираться.

Постановка задачи

Отображение модального окна нужно для:

  • Отображения Web-страницы внешнего провайдера
  • Приобретение user id от внешнего провайдера для идентификации пользователя и authentication token от Azure — тот, что нужен для дальнейших запросов к бакенду.
  • Возврат User ID в экземпляр класса MobileServiceUser, а authentication token в экземпляр класса MobileServiceClient.

Лично я противник модальных окон, следственно всё сделаем в цельном окне, с использованием асинхронных способов.

Реализация задумки

Перед тем как начать, вы обязаны зарегистрировать Ваше приложение у себя в Microsoft Account для приобретения кода заказчика и тайного ключа, именно Microsoft-провайдер я буду применять для примера.

В вёрстке нам потребуются:

  1. WPF окошко с Frame, в тот, что мы будем грузить надобные нам страницы.
  2. Примитивную страничку «LoginPage» c кнопкой «Login».
  3. Вторая страница — легко контейнер для WebBrowser компонента — «WebLoginPage».

В коде реализуем способ-растяжения для класса MobileServiceClient:

public static class DesktopWebLoginExtension
    {
    public async Task<MobileServiceUser> LoginAsync(this MobileServiceClient client, MobileServiceAuthenticationProvider provider, LoginPape loginPage)
        {
            Uri startUri = new Uri(client.ApplicationUri, "login/"   provider.ToString().ToLowerInvariant());
            Uri endUri = new Uri(client.ApplicationUri, "login/done");

            LoginResult externalAuthProviderLoginResult = await loginPage.GetLoginResultAsync(startUri, endUri);

            if (externalAuthProviderLoginResult == null) 
            {
                return null;
            }

            var returnServiceUser = new MobileServiceUser(externalAuthProviderLoginResult.UserId);
            returnServiceUser.MobileServiceAuthenticationToken = externalAuthProviderLoginResult.AuthenticationToken;
            client.CurrentUser = returnServiceUser;
            return returnServiceUser;        
      }
    }

Разберём:

  1. Как добавочный параметр наш способ принимает loginPage — что безусловно является дерзким нарушением software layer, но для примера сойдет.
  2. startUri и endUri собраны исходя из этой документации.
  3. loginPage.GetLoginResultAsync — асинхронный способ, тот, что вернёт нам экземпляр класса LoginResult
  4. Дальше происходит заполнение нужных нам полей для последующей работы.

А вот и сам класс-контейнер, в последствии он будет заполнен из JSON-результата:

public class LoginResult
    {
        public string UserId { get; set; }
        public string AuthenticationToken { get; set; }
    }

Код страницы WebLoginPage выглядит вот так:

public class WebLoginPage : Page
    {

        private Uri startUri;
        private Uri endUri;

        public delegate void LoginCompleteEventHandler(LoginResult result);
        public event LoginCompleteEventHandler UserLogedIn;

        public LoginBrowserPage()
        {
            InitializeComponent();
            webBrowser.Navigating  = webBrowser_Navigating;
        }
     public Task<LoginResult> GetLoginResultAsync(Uri startUri, Uri endUri)
        {
            this.startUri = startUri;
this.endUri = endUri;

            var returnTask = new TaskCompletionSource<LoginResult>();

            webBrowser.Navigate(startUri);

            this.UserLogedIn  = (r) => { returnTask.SetResult(r); };

            return returnTask.Task;
        }

    internal void webBrowser_Navigating(object sender, NavigatingCancelEventArgs e)
        {
            if (e.Uri.Equals(this.endUri))
            {
                string uri = e.Uri.ToString();

                if (uri.LastIndexOf("#token=") != 0)
                {
                    var startOfToken = uri.IndexOf("#token=")   "#token=".Length;
                    uri = uri.Substring(startOfToken).Replace("%2C", ",");
                    JObject jsonObj = JObject.Parse(uri);
                    var userId = jsonObj["user"]["userId"].ToObject<string>();
                    var authToken = jsonObj["authenticationToken"].ToObject<string>();

                    UserLogedIn(new LoginResult() { UserId = userId, AuthenticationToken = authToken });
                }
                else
                {
                    UserLogedIn(null);
                }
            }
        }
    }

Разберём:

  1. Мы объявили событие, которое будет появляться по заключении аутентификации в нашем мини браузере.
  2. GetLoginResultAsync — способ, тот, что «ждёт» событие заключения процесса авторизации с поддержкой восхитительного класса TaskCompletionSource. Так мы добились цельной «линии ожидания» из асинхронных способов. С огромный натяжкой это дозволено назвать модальной загрузкой страницы во фрейм с возвратом итога в вызывающую функцию (асинхронно) — как и советует нам делать Microsoft с приходом асинхронных способов.
  3. webBrowser_Navigating — в этом обработчике события мы усердно десериализуем JSON-результат от обслуживания и получаем сокровенные UserId и AuthenticationToken.
  4. Вызываем сокровенное событие — позже чего все асинхронные вызовы завершаются и дерзкий способ получает итог аутентификации.

Сейчас ничего не мешает нам в надобном месте написать:

var user = await MobileServiceClient.LoginAsync(MobileServiceAuthenticationProvider.MicrosoftAccount, webLoginPage);

P.S. При заключении наш webBrowser предложит нам скачать JSON результат от обслуживания. Это задача IE движка решается вот таким ключиком в реестре:

Windows Registry Editor Version 5.00;
[HKEY_CLASSES_ROOTMIMEDatabaseContent Typeapplication/json]
«CLSID»=”{25336920-03F9-11cf-8FD0-00AA00686F13}”
«Encoding»=hex:08,00,00,00

Итог

С поддержкой выше переведённого кода мы сняли неприятное лимитацией связанное с неосуществимостью легко вызвать MobileService.LoginAsync в десктопном приложении и получить итог аутентификации асинхронно.

Спасибо за внимание.

Ссылки:

Windows Azure Mobile Services REST API Reference
Get started with authentication in Mobile Services
Register your application in Google

Источник: programmingmaster.ru

Оставить комментарий
Форум phpBB, русская поддержка форума phpBB
Рейтинг@Mail.ru 2008 - 2017 © BB3x.ru - русская поддержка форума phpBB