Проверка подлинности, учетные данные и профиль пользователя
Хранилище учетных данных
Одной из причин, по которой приложение может постоянно запрашивать у пользователя учетные данные может быть то, что у приложения просто нет по-настоящему безопасного места для хранения учетных данных и последующего их получения, которое, кроме того, изолировано от любых других приложений. Это – задача хранилища учетных данных, для работы с которым используется API Windows.Security.Credentials.PasswordVault (http://msdn.microsoft.com/library/windows/apps/br227081.aspx ).
С помощью хранилища, любые учетные данные могут быть представлены с помощью объекта Windows.Security.Credentials.PasswordCredential (http://msdn.microsoft.com/library/windows/apps/windows.security.credentials.passwordcredential.aspx ), как мы уже видели, когда говорили об API фоновой передачи данных. Вы можете создать и инициализировать учетные данные следующим образом:
var cred = new Windows.Security.Credentials.PasswordCredential(resource, userName, password);
Другая возможность заключается в создании неинициализированного объекта учетных данных и в индивидуальном заполнении его свойств:
var cred = new Windows.Security.Credentials.PasswordCredential(); cred.resource = "userLogin" cred.userName = "username"; cred.password = "password";
Объект, представляющий учетные данные так же содержит свойство типа IPropertySet (http://msdn.microsoft.com/library/windows/apps/windows.foundation.collections.ipropertyset.aspx ), которое называется properties, с его помощью можно управлять этими данными.
В любом случае, когда вы получаете учетные данные от пользователя и хотите их сохранить, создайте объект PasswordCredential и передайте его методу PasswordVault.add:
var vault = new Windows.Security.Credentials.PasswordVault(); vault.add(cred);
Обратите внимание на то, что если вы добавите в хранилище учетные данные со значениями a resource и userName , которые уже существуют, новые данные заменят старые. И если по какой-либо причине вы хотите удалить данные из хранилища вызовите метод PasswordVault.remove с этими учетными данными.
Более того, даже хотя объект PasswordCredential выглядит содержащим имя пользователя и пароль, пароль может быть чем угодно, что вам нужно безопасно сохранить, например, маркером доступа. Как мы увидим в следующем разделе, при аутентификации посредством OAuth может предоставляться подобный маркер, в таком случае вам может понадобиться сохранить что-то вроде "Facebook_Token" в свойстве объекта, представляющего учетные resource, имя приложения в userName, и маркер – в свойстве password. Это – полностью оправданное и ожидаемое использование.
Как только учетные данные попадают в хранилище, они остаются дам для использования при следующих запусках приложения, до тех пор, пока вы не вызовите метод remove или пользователь явным образом не удалит их, с помощью команды Панель управления > Учетные записи пользователей и семейная безопасность > Диспетчер учетных данных (Control Panel > User Accounts and Family Safety >Credential Manager). На доверенном ПК (что требует входа в него с использованием учетной записи Microsoft), Windows автоматически и безопасно перемещает содержимое хранилища на другие устройства (это можно выключить с помощью команды Параметры ПК > Синхронизация параметров > Пароли (PC Settings > Sync Your Settings > Passwords)). Это помогает создать единую рабочую среду для вашего приложения, когда пользователь перемещается между устройствами .
Таким образом, при запуске приложения, даже при первом – всегда проверяйте хранилище на предмет сохраненных учетных данных. Есть несколько методов класса PasswordVault для того, чтобы это делать:
- findAllByResource Возвращает массив (вектор) объектов учетных данных по заданному идентификатору ресурса. Подобным образом можно получить имя пользователя и пароль, которые переместились с другого устройства, так как приложение сохранило учетные данные на другом компьютере с тем же самым идентификатором ресурса.
- findAllByUserName Возвращает массив (вектор) объектов учетных данных по заданному имени пользователя. Это полезно, если вы знаете имя пользователя и хотите получить все учетные данные для множества ресурсов, к которым подключено приложение.
- retrieve Возвращает единственный объект учетных данных по заданному ресурсу идентификатора и имени пользователя. Опять же, сочетанию имени пользователя и ресурса соответствует только один объект в хранилище.
- retrieveAll Возвращает вектор всех учетных данных, имеющихся в хранилище для данного приложения. Ветор содержит копию состояния хранилища и не обновляется, если происходят последующие обновления учетных данных в хранилище.
Есть небольшое различие между методами findAll и retrieve в вышеприведенном списке. Метод retrieve предоставляет полностью заполненные объекты учетных данных. А методы findAll, с другой стороны, возвращают объекты, в которых свойство password не заполнено. Это предотвращает дешифрование пароля на основе потенциально большого набора учетных данных. Для того, чтобы заполнить это свойство для каждого отдельного объекта, вызовите метод PasswordCredential.retievePassword.
Для дальнейшей демонстрации работы с хранилищем учетных данных – код здесь очень прост – обратитесь к примеру "Хранилище учетных данных" ( http://code.msdn.microsoft.com/windowsapps/PasswordVault-f01be74a). Он показывает варианты работы для одного пользователя/одного ресурса (Сценарий 1), одного пользователя/несколькоих ресурсов (Сценарий 2), нескольких пользователей/нескольких ресурсов (Сценарий 3), а так же – полную очистку хранилища (Сценарий 4).
Брокер веб-проверки подлинности
Хотя приложения могут принимать учетные данные пользовтеля и управлять ими собственными силами, поддерживая пользователей, возможно, с возможностью создания учетных записей для конкретных приложений или конкретных сервисов (обычно с помощью чудо-кнопки Параметры, как обсуждалось в Главе 2 курса "Пользовательский интерфейс приложений для Windows 8, созданных с использованием HTML, CSS и JavaScript", а так же в материале "Руководство и контрольный список для элементов управления входом" (http://msdn.microsoft.com/library/windows/apps/hh965453.aspx ), может возникнуть необходимость использовать учетную запись, которую пользователь уже создал посредством другого OAuth-поставщика, остобенно когда вы хотите использовать ресурсы этого поставщика. Вероятно, вы уже сталкивались с этим на многих веб-сайтах, куда можно войти через другой сайт, наподобие Facebook. Конечно, это обычно означает переход с исходного сайта на сайт поставщика – процесс, который отлично происходит в веб-браузере, но не столь привлекателен в контексте приложения!
Для этой цели Windows предоставляет Брокера веб-проверки подлинности (Web Authentication Broker), который делает то же самое, не покидая контекст приложения. Приложение предоставляет URI для страницы проверки подлинности на внешнем сайте (необходимо использовать схему URI-схему https://, в противном случае вы получите ошибку, вызванную неподходящим параметров). Затем брокер создает новый хост-процесс для веб в его собственном контейнере приложения, в который и загружает указанную веб-страницу. Пользовательский интерфейс для этого процесса показан в виде находящегося поверх приложения диалогового окна, рис. 8.2, для чего я использовал Сценарий 1 примера "Брокер веб-проверки подлинности" (http://code.msdn.microsoft.com/windowsapps/Web-Authentication-d0485122 ).
Рис. 8.2. Пример использования брокера веб-проверки подлинности со страницей входа в систему сервиса Facebook
Примечание. Для того, чтобы запустить пример, вам понадобятся ID приложения для каждого из поставщиков аутентификации в различных сценариях. Для Facebook в Сценарии 1, посетите http://developers.facebook.com/setup и создайте App ID/API Key для тестового приложения.
В случае с Facebook, процесс аутентификации включает в себя больше, чем просто проверка учетных данных пользователя. Кроме того, нужно получить различение на других возможности, которыми собирается пользоваться приложение (пользователь может независимо от приложения отменить их на сайте Facebook). В результате, процесс аутентификации может включать в себя переходы на дополнительные страницы, каждая из которых будет отображаться в брокере веб-проверки подлинности, как показано на рис. 8.3. В данном случае идентификатор приложения, ProgrammingWin8_AuthTest, это тот, что я только что создал посредством страницы настроек разработчика Facebook для целей этой демонстрации.