Опубликован: 15.05.2013 | Доступ: свободный | Студентов: 266 / 9 | Длительность: 24:25:00
Специальности: Системный архитектор
Лекция 8:

Проверка подлинности, учетные данные и профиль пользователя

< Лекция 7 || Лекция 8: 1234 || Лекция 9 >

В интерфейсе брокера веб-проверки пользователь может пройти через множество страниц сайта поставщика (обратите внимание на то, что кнопка Назад, около заголовка "Сonnecting to a service" (Подключение к сервису) полностью закрывает это окно). Но все это приводит к к вопросу: как брокер узнает, что аутентификация завершилась? Последний шаг в процессе аутентификации на правой части рис. 8.3. – нажатие на кнопку Allow (Разрешить) , после чего обычно Facebook отображает страницу с информацией об успешном входе. В контексте приложения, однако, нам не нужно отображать подобную страницу – скорее нужно закрыть окно брокера и вернуться в приложение с результатом аутентификации. Более того, многие OAuth-поставщики даже не имеют подобной страницы. Что же нам делать?

К счастью, брокер уже это учитывает. Как мы скоро увидем, приложение просто предоставляет URI для последней страницы процесса работы спровайдером. Когда брокер обнаруживает, что осуществился переход на эту страницу, он закрывает свой интерфейс и передает приложению ответ.

Как часть этого процесса, Facebook сохраняет информацию о различных разрешениях на собственном сервере для каждого конкретного пользователя, поэтому, если приложение снова запустит процесс аутентификации, пользователь не увидите тех же страниц, что показаны на рис. 8.3. Пользователь может, конечно, управлять этими разрешениями, когда посещает страницу Facebook через веб-браузер, если пользователь удалит здесь информацию о приложении, то при повторном входе через приложение снова будут показаны те же страницы.

В WinRT брокер представлен классом Windows.Security.Authentication.Web.WebAuthenticationBroker (http://msdn.microsoft.com/library/windows/apps/windows.security.authentication.web.webauthenticationbroker.aspx ). Аутентификация производится с помощью его методов authenticateAsync. Я написал здесь "методов", так как имеется два их варианта. Мы посмотрим на один из них здесь и вернемся ко всторому в следующем разделе, "Режим единого входа".

Первый вариант метода authenticateAsync принимает три аргумента:

  • options Любая комбинация значений из перечисления WebAuthenticationOptions (http://msdn.microsoft.com/library/windows/apps/windows.security.authentication.web.webauthenticationoptions.aspx ) (скомбинированных с помощью побитового OR). Возможные значения: none (по умолчанию), silentMode (не отображается интерфейс), useTitle (возвращает в результатах заголовок окна веб-страницы), useHttpPost (возвращает в результатах тело страницы), и useCorporateNetwork (для вывода в контейнере приложения веб-страниц с возможностями Частные сети (клиент и сервер) (Private Networks (Client & Server)), Корпоративная аутентификация (Enterprise Authentication), Общие сертификаты пользователей (Shared User Sertificates); кроме того, приложение должно объявить эти возможности).
  • requestUri URI (Windows.Foundation.Uri) для страницы аутентификации поставщика с параметрами, которые нужны сервису; повторюсь, здесь необходимо использовать схему URI https://.
  • callbackUri URI (Windows.Foundation.Uri) конечной страницы, отображаемой в процессе аутентификации у поставщика. Брокер использует этот адрес для определения момента закрытия собственного интерфейса .

Результат, передаваемый обработчику завершения authenticateAsync это объект WebAuthenticationResult (http://msdn.microsoft.com/library/windows/apps/windows.security.authentication.web.webauthenticationresult.aspx ). Он содержит следующие свойства: responseStatus (типа WebAuthenticationStatus (http://msdn.microsoft.com/library/windows/apps/windows.security.authentication.web.webauthenticationstatus.aspx ), которое может принимать значения success, userCancel, или errorHttp), responseData (строка, содержащая заголовок страницы и ее тело, если, соответственно, установлены опции useTitle и useHttpPost), и responseErrorDetail (номер ошибки HTTP).

Вообще говоря, приложению особенно интересно содержимое responseData, так как здесь будет содержаться маркер или другие ключи, которые могут понадобиться ему позже. Посмотрим на это снова, в контексте Сценария 1 примера "Брокер веб-проверки подлинности" (http://code.msdn.microsoft.com/windowsapps/Web-Authentication-d0485122 ). Установим точку основа в обработчике завершения authenticateAsync (строка 59 или поблизости), и запустим пример, введем ID приложения, который был создан ранее и нажмем Launch (Запустить). (Обратите внимание на то, что параметр callbackUri установлен в https://www.facebook.com/connect/login_success.html, это страница, на которой завершается процесс аутентификации).

В случае с Facebook, responseData содержит строку такого вида:

        https://www.facebook.com/connect/login_success.html#access_token=<token>
        expires_in=<timeout>
      

Здесь в <token> Содержится куча алфавитно-цифровой абракадабры, <timeout>

  • это некоторый период, заданный Facebook. Если вы вызовете какое-нибудь API Facebook, что весьма вероятно, так как вы не случайно проходите аутентификацию через Facebook, <token>
  • это настоящее богатство, так как именно с его помощью вы аутентифицируете пользователя, когда выполняете вызовы к этому API.

Этот маркер доступа затем сохраняют в хранилище учетных данных для последующего использования, когда приложение будет перезапущено после приостановки или остановки. (В случае с Facebook, вам не нужно беспокоиться об истечении срока действия этого маркера, так как API обычно сообщает об этом как об ошибке и имеет встроенный процесс обновления маркера). Что-то похожее вам придется делать при работе с другими поставщиками аутентификация, обращаясь, конечно, к их документации, которая сообщит о том, что вы получите в ответе сервера и как использовать и/или обновлять ключи или маркеры при необходимости.

В целом, ключевое преимущество веб-аутентификации это то, что пользователь никогда не предоставляет учетные данные приложению – пользователь передает их лишь гораздо более доверенному поставщику. С точки зрения приложения, так же, ему никогда не требуется управлять этими учетными данными, лишь токеном, который возвращает поставщик. По той же причине, при запуске брокера, который мы видели здесь, всегда будет отображаться страница входа с пустыми полями, независимо от флага Оставаться в системе (Keep Me Logged In), так как приложение не хранит подобных данных, и любые куки и состояния сессии находятся внутри окружения брокера и не сохраняются. Таким образом, если приложению нужно дать пользователю доступ к тому же сервису с другими учетными данными, ему достаточно запустить брокер, как ранее, и заменить токены или ключи, которые были сохранены при последнем сеансе аутентификации.

Говоря о поставщиках, страница про OAuth в Википедии ( http://ru.wikipedia.org/wiki/OAuth) содержит перечисление существующих поставщиков аутентификации. Пример "Брокер веб-проверки подлинности", в свою очередь, показывает как работать с Facebook (Сценарий 1), Twitter (Сценарий 2), Flickr (Сценарий 3), и Google/Picasa (Сценарий 4), и так же предоставляет общий интерфейс для любых других сервисов (Сценарий 5).

Полезно просмотреть эти разные сценарии, так как Facebook и Google используют протокол OAuth 2.0, requestUri для каждого выглядитдовольно простым (если исключить перенос слов:

https://www.facebook.com/dialog/oauth?client_id=<client_id>
&redirect_uri=<redirectUri>
&
scope-read_stream&display=popup&response_type=token

https://accounts.google.com/o/oauth2/auth?client_id=<client_id>
&redirect_uri=<redirectUri>
&
response_type=code&scope=http://picasaweb.google.com/data
https://www.facebook.com/dialog/oauth?client_id=<client_id>
&redirect_uri=<redirectUri>
&
scope-read_stream&display=popup&response_type=token
      

Здесь <client_id>и <redirectUri> заменяется на то, что задано приложением. Twitter иFlickr, в свою очередь, используют вместо этого протокол OAuth 1.0a, в итоге, требуется включать длинный маркер OAuth в аргумент requestUri для authenticateAsync. Подробности вы можете увидеть в коде примера.

Совет. События брокера веб-проверки подлинности можно просмотреть окне Просмотр журналов событий (Event Viewer) в разделе Журналы приложений и служб > Microsoft > Windows > WebAuth> Operational (Application And Services Logs >Microsoft > Windows > WebAuth > Operational). Это может быть полезным для целей отладки, так как здесь можно увидеть данные, которые, в противном случае, скрыты за непрозрачным окружением брокера.

Режим единого входа

Все, касающееся хранилища учетных данных и брокера веб-проверки подлинности, отлично работает для минимизации того, как часто приложение донимает пользователя вопросами о вводе учетных данных. Когда речь идет об отдельном приложении, очень хороша возможность один раз запросить учетные данные и не запрашивать их снова до тех пор, пока пользователь явным образом не выйдет из системы. Но как насчет нескольких приложений. Представьте себе, что вы установили несколько десятков или сотен приложений из Магазина Windows, использующих внешних поставщиков аутентификации. Это может означать, что вы будете вводить учетные данные для входа в аккаунты Facebook, Twitter, Google, LinkedIn, Tumblr, Yahoo, или Yammer в каждое приложение, которое их использует. Очевидно, в каждом отдельном приложении это нужно будет лишь раз, но общий эффект оказывается утомляющим и надоедливым!

С точки зрения пользователя, как только он аутентифицировался посредством некоего поставщика в одном приложении, у него возникает ощущение, что и другие приложения, если возможно, должны воспользоваться результатами этой аутентификации. Конечно, некоторые приложения могут нуждаться в запросе дополнительных разрешения и некоторые поставщики могут это не поддерживать, но в идеале, опять же, мы должны максимально оградить пользователя от излишней суеты и не беспокоить его там, где это возможно.

Концепция режима единого входа (SSO) в этом и заключается: проверка подлинности пользователя в одном приложении (или во всей системе, в случае с учетной записью Microsoft) приводит к возможности входа в другие приложения, которые используют того же поставщика. В то же время, каждое приложение обычно должно получить собственные ключи доступа или маркеры, так как их не следует делать общими для разных приложений. В итоге весь фокус заключается в том, чтобы эффективно произвести тот же процесс аутентификации, который мы видели, только сделать его, не показывая пользовательский интерфейс до тех пор, пока это действительно не будет нужно.

Это можно реализовать с помощью брокера веб-проверки подлинности с помощью одного из вариантов authenticateAsync, который принимает лишь аргументы options и requestUri. В данном случае options часто устанавливается в WebAuthenticationOptions.silentMode для того, чтобы предотвратить показ интерфейса рокера (но это не обязательно).

Для того, чтобы режим silentMode заработал, брокеру все еще нужно узнать, когда завершится процесс проверки подлинности. Поэтому, какой же callbackUri ему использовать для сравнения и как поставщик узнает то, что ему нужно? Это напоминает ситуацию, когда брокер находится в системе, всегда скрытый, в то время, Как поставщик терпеливо ожидает ввода данных на веб-страницу, которая полностью невидима! Что, на самом деле происходит, это то, что authenticateAsync ожидает, когда поставщик перейдет по особому callbackUri , которое выглядит как ms-app://<app_package> /<secret_sauce>, после чего результат ответа поставщика будет передан в виде асинхронного результата.

Конечно, данный URI неичего не значит для поставщика …если только его не оповестили об этом заранее и он не ожидает появления подобного URI в своей среде.

Это сообщает нам о том факте, что режим единого входа работает только если провайдер имеет средства (API или что-то вроде того), посредством которого приложение может сообщить о своих намерениях. Для того, чтобы это понять, рассмотрим полный рабочий процесс "тихой" аутентификации:

  • Приложение, которое желает использовать режим единого входа, подписывается, с помощью одного из двух средств, на получение собственного URI ms-app://, который так же называется SID URI. Во-первых, это возможно с помощью вызова статического метода WebAuthenticationBroker.getCurrentApplicationCallbackUri. Этот вызов возвращает объект Windows.Foundation.Uri, строковое свойство которого absoluteUri, это как раз то, что вам нужно. Во-вторых, это можно реализовать на странице Магазина Windows Информационная панель > Управление облачными службами > Дополнительные функции > Проверка подлинности приложения (Dashboard > Manage Your Cloud Services > Advanced Features > Application Authentication), где вы сможете увидеть строку, выглядящую примерно так: ms-app://s-1-15-2-477157379-2961032073-432767880-3229792171-202870256-1369967874-2241987394/.
  • Если нужно, приложение затем вызывает API поставщика для регистрации этого SID URI (обычно у поставщика есть страница для указания приложения, где вводят эти данные).
  • При создании аргументов requestUri для authenticateAsync, приложение добавляет свой SID URI в качестве значения для параметра &redirect_uri=.
  • Приложение вызывает authenticateAsync с опцией silentMode.
  • Когда поставщик обработает параметры requestUri, он проверяет, зарегистрировано ли значение redirect_uri, и, если это не так, отвечает сообщением об ошибке.
  • Производя проверку приложения, поставщик затем, не задавая вопросов (если возможно) производит проверку подлинности и переходит по redirect_uri, не забыв включить маркеры и ключи доступа в данные ответа.
  • Брокер веб-проверки пользователя обнаруживает этот переход и сравнивает его адрес со своим callbackUri. Обнаружив совпадение, брокер может завершить асинхронную операцию и предоставить приложению данные ответа поставщика.

Опять же, у поставщика должны быть средства, с помощью которых разработчик или приложение могут зарегистрировать SID URI, он должен проверить SID URI, когда оно оказывается в запросе на проверку подлинности, и должен выдать подходящий ответ на эту страницу, когда проверка подлинности завершена. Таким образом, поставщик или приложение ответственны за регистрацию SID URI и за включение его в requestUri. (Ух ты, сколько же URI!)

При всем этом, все еще возможно, что проверка подлинности может не удастся по каким-то другим причинам. Например, если пользователь не установил полномочия приложения для этого (как в случае с Facebook), "тихая" проверка подлинности не возможна. Таким образом, приложение пытается использовать режим единого входа, вызывает сначала authenticateAsync соответствующего вида, а если это не удается, пытается вызвать его более длинный вариант (с показом пользовательского интерфейса), как описано в предыдущем разделе.

< Лекция 7 || Лекция 8: 1234 || Лекция 9 >