Visual Basic, .NET, ASP, VBScript
 

   
 

Образование: - в 1996 г. окончил МГУ им. М.В.Ломоносова, факультет вычислительной математики и кибернетики
Общий стаж работы: - с 1994 г.
Стаж работы в IT-индустрии: - с 1994 г.

Предыдущие места работы, должности:
1994-1996 - НПП "Гарант-Сервис", программист;
1996-1998 - ЗАО "Гарант-Парк", системный аналитик;
1998-1999 - ЗАО "Гарант-Парк", руководитель отдела программирования;
1999-2000 - ООО "Гарант-Парк-Интернет", руководитель отдела программирования.

 
     
   
 

Заостровцев Николай Metric


В предыдущей статье мы рассматривали, что такое Microsoft Passport. Теперь изучим, как подключить службу единого входа.

Установка необходимого программного обеспечения

Для начала необходимо установить Microsoft .NET Passport SDK 2.1. В процессе установки выбираем, что устанавливаем в режиме Preproduction/Test Environment.

Система может работать либо в тестовом режиме (PreProduction), либо в действующем (Production). Режим определяет сервера идентификации, с которыми происходит взаимодействие. В тестовом режиме модуль работает с сервером current-login.passporttest.com, а в действующем – с login.passport.com. Эти сервера имеют разные базы зарегистрированных сайтов и пользователей. Переводить систему в режим Production необходимо только после получения Production Key.

Получение тестового ключа

Начинать подключение приложения можно и с тестовым ключом (Site ID = 1), входящим в состав SDK. Но я рекомендую потратить 10 минут, чтобы получить и настроить собственный ключ.

Получить тестовый ключ можно через систему .NET My Services Manager. В системе необходимо идентифицировать себя через паспорт, после чего возможно создание собственных приложений в разделе My Applications.

При заполнении полей критическими для работы являются только следующие параметры:

  • Domain Name – домен, в котором находится сайт. Указывайте домен второго уровня. Существует ограничение, что все другие адреса, которые Вы будете указывать, должны находиться в этом домене.
  • Default Return URL – адрес возврата по умолчанию. Если при выполнении авторизации не будет указан адрес возврата, то будет использоваться этот.
  • Expire Cookie URL - указываем адрес, который будет очищать Cookie по окончании регистрации, например, http:///expire.asp. Если данная страница будет отсутствовать или некорректно работать, то пользователь не сможет осуществить процедуру выхода.
После завершения регистрации возвращаемся в раздел My Applications, выбираем только что созданное приложение. Далее выбираем операцию Download key и получаем себе тестовый ключ. Также при этом запоминаем номер сервера (Site ID).

Регистрация тестового ключа

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

Запускаем Passport Administration Utility, нажимаем New Web Site. Указываем имя сервера, имя хоста и IP адрес. В оставшихся полях заполняем только Site ID и нажимаем Commit Changes.

Когда Вы будете обращаться программно к объектам Passport Manager, то не сможете указать Site ID, который использовать. Система определяет его самостоятельно по имени хоста и IP адресу (эта пара должна быть уникальна в рамках физического сервера). Сначала проверяется IP адрес, а потом имена хостов внутри этого адреса.

После того, как Вы завели новую конфигурацию для паспорта, можно установить сам ключ. Для этого надо выполнить два запуска программы-ключа с параметрами:

  • Partner_1.exe /addkey /s
  • Partner_1.exe /makecurrent /t 0 /s
Где - Ваш Site ID, а соответствует значению, введенному в поле Web Site Name.

После этого необходимо перезагрузить службу IISADMIN.

Подключение паспорта

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

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

Такая схема подключения используется на сервере GotDotNet.RU . Сервер идентифицирует через паспорт, а дополнительно спрашивает у пользователя псевдоним (для форумов и пробного хостинга) и адрес электронной почты.

Для этого необходимо реализовать следующие процедуры:

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

Общий код

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

В примере будет использоваться функции, зависимые от проекта:

  • IsRegisterPage - проверяет, находимся ли мы сейчас на странице регистрации
  • UserExists - проверяет по PUID есть ли такой пользователь во внутренней базе. PUID является уникальным кодом пользователя в паспорте и может быть использован для установления однозначного соответствия.
  • ThisURL - возвращает адрес текущей страницы со всеми параметрами, либо без служебных параметров службы паспорта (t,p,did).

Const tNoTicket = 0
Const tStaleTicket = 1
Const tValidTicket = 2
Const lPassportTimeout = 3600
Const lPassportLang = 1049


' Создаем объект Passport Manager
Set oMgr = Server.CreateObject("Passport.Manager")
' После проведения успешной авторизации пользователь
' возвращается на сервер и при этом в аргументах
' передаются дополнительные параметры, необходимые для
' паспорта. Для корректного завершения входа
' необходимо вызвать метод FromNetworkServer, 
' который сохранит необходимые параметры в cookie,
' а потом удалить лишние аргументы из адреса.
' Для этого перенаправляем пользователя на
' текущую страницу, удаляя параметры t,p,did.
' Жаль, что Microsoft не ввел какие-нибудь префиксы
' для своих параметров. Легко попасть в ситуацию,
' когда страница уже имела параметры с такими именами
' и конфликт налицо.
'
' Если этот метод не вызвать, то вход не завершится успешно.
If oMgr.FromNetworkServer Then
    ' Функция ThisURL возвращает текущий URL, при
    ' необходимости удаляя из него фикс. параметры
    Response.Redirect ThisURL(True)
    Response.End
End If

' Проверим состояние идентификационного ключа пользователя
If oMgr.IsAuthenticated(lPassportTimeout) Then
   ' пользователь идентифицирован

   ' PUID - уникальный код пользователя в паспорте.
   sPUID = oMgr.HexPUID

   ' Проверим, что если мы не находимся на странице
   ' регистрации (ввода дополнительных данных)
   ' и значение в сессии не установлено, то надо
   ' попытаться установить соответствие
   ' между паспортом и внутренним пользователем

   If Not IsRegisterPage() And Len(Session(sSesUID)) = 0 Then
   	' Необходимо проверить
   	lUID = UserExists( sPUID)
   	If lUID > 0 Then
   		' Такой пользователь есть
   		Session(sSesUID) = lUID
   	Else
   		' Такого пользователя нет.  Это значит,
                ' что надо отправить его на страницу
   		' ввода дополнительных данных.
   		Response.Redirect sRegURL
   	End if
   End if
ElseIf oMgr.HasTicket Then
   ' у пользователя есть ключ, но время его
   ' жизни уже истекло необходимо обновить ключ.
   ' Это выполняется автоматически.
   oMgr.LoginUser Server.URLEncode(ThisURL(False)), _
         lPassportTimeout, , , lPassportLang
   ' далее не должно быть никакого кода, LoginUser
   ' выполняет Redirect
Else
   ' пользователь не авторизован
   ' очистим его значение в сессии
   Session(sSesUID) = Empty
End If

Регистрация пользователя во внутренней системе

После входа через паспорт, если мы не нашли соответствия между паспортом и пользователями во внутренней базе, мы отправляем пользователя на страницу ввода дополнительной информации о себе. Чтобы упростить пользователю процедуру ввода данных, будем часть информации брать из паспорта.

Отметим сразу несколько моментов:

  • При установке Passport SDK он устанавливается с Site ID = 1. Можно создавать тестовые реализации и с этим Site ID, не получая собственный ключ через .NET My Services Manager. Но при этом Вы гарантированно не получите никаких данных о пользователе.
  • При работе в PreProduction режиме Вы сможете получить данные только о пользователях, которые зарегистрировались в тестовом режиме. При работе в PreProduction режиме в форме ввода имени и пароля будет ссылка на получение нового паспорта. Необходимо получить такой паспорт и использовать этих пользователей для тестирования. Остальных пользователей Вы сможете только идентифицировать.
  • Получить данные можно, только если пользователь отметил соответствующие разрешающие флаги в своем профайле.
Получить данные можно с помощью метода Profile. Перед тем, как вызывать метод Profile , необходимо, чтобы был вызван хотя бы один из методов HasProfile, HasTicket, IsAuthenticated и вернул значение True.

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

Со словарями сразу начинаются проблемы:

  1. Список значений словарей получается не с сервера, а хранится локально. Это явный просчет в архитектуре паспорта. Словари на сервере могут измениться, а их актуальность на клиенте никем не гарантируется.
  2. В словарях для русского языка (поддиректория 1049) установлена кодировка .1252 вместо .1251.
  3. Часть словарей для русского языка, например, города (city.dat) – просто пустые.
  4. Планируется, что значение по коду мы получаем значение из словаря, используя объект LookupTable. Данный объект позволяет быстро загрузить текстовый файл и далее получить значение по ключу. Но даже этим воспользоваться нельзя. Например, Россия описана в справочнике стран строкой «181,Россия,4,2,RU,7». Объект LookupTable может по коду 181 вернуть значение «Россия,4,2,RU,7». А паспорт нам возвращает значение «RU».
В результате пользоваться значениями на базе словарей практически невозможно. Для тех полей, для которых словари все-таки есть, нужно писать самостоятельную процедуру обработки. А для тех, что нет – увы, придется пользователю вводить информацию заново вручную.

Далее нам остается только сохранить введенные данные в свою систему.

Отображение логотипа для входа/выхода

Для отображения логотипа достаточно осуществить один вызов метода LogoTag2. Результатом будет строка, содержащая необходимый HTML-код.
Response.Write( oMgr.LogoTag2(Server.URLEncode _
     (ThisURL(False)), lPassportTimeout, , , lPassportLang))

Выход из системы

Успешный выход из системы будет осуществлен только в случае корректной работы файла, который Вы указали в поле Expire Cookie URL в .NET My Services Manager. В качестве этого файла можно взять файл expire.asp, который есть в тестовом сервере в составе SDK. Дополнительно в него можно добавить вызов Session.Abandon для завершения сессии на своем сайте.

Активизация

На этом подключение паспорта в режиме PreProduction завершено. Теперь, чтобы активизировать сайт, необходимо:
  • Заключить договор с паспортом.
  • Осуществить оплату за использование.
  • Через .NET My Services Manager осуществить запрос на перевод сайта в режим Production.
  • Дождаться получения по почте дискеты с ключом. По соображениям безопасности, других способов доставки нет.
  • Через Passport Administration Utility перевести паспорт в режим Production и установить новый полученный ключ.

Настройка внешнего вида

Базовая настройка внешнего вида позволяет Вам размещать логотипы и текст на формах. Но в паспорте предусмотрен механизм и более тонкой настройки внешнего вида.

Для этого при регистрации сервера в .NET My Services Manager служат параметры:

  • Cobrand URL- адрес страницы, содержащей JavaScript, которая заполняет фиксированные переменные. Укажем http:///cobrand.js
  • Cobrand CSS URL – адрес страницы со стилями. На страницы регистрации она будет включена через обычный link rel=stylesheet. Поставьте ссылку на файл со стилями вашего сайта.
При этом оставшиеся параметры (Cobrand Image URL, Cobrand Image2 URL, Cobrand Instruction Text) уже использоваться не будут, но, по-прежнему, являются обязательными для заполнения.

Файл, определяемый адресом Cobrand URL, должен содержать инициализацию фиксированных переменных JavaScript. Переменные должны содержать строки с HTML-кодом, который будет вставлен в определенные места.

  • CBLoginHead – значение будет добавлено в раздел HEAD на страницу входа.
  • CBLoginBody – аналогично в раздел BODY.
  • CBRegistrationHead, CBRegistraionBody – аналогично для страницы регистрации.
CBLoginBody, CBRegistrationBody должен содержать подстроку PASSPORT_UI. Вместо этой строки будут добавлены соответствующие формы паспорта. В качестве примера файла можно посмотреть http://www.gotdotnet.ru/cobrand.js.

Дополнительно Вы имеете возможность настраивать внешний вид не статически, а в зависимости от места вызова. Для этого методы LogoTag2, LoginUser, AuthURL2 имеют дополнительные параметр coBrandArgs. Значение этого параметра будет передано Вашему скрипту и может быть нужным образом обработано.

Использование паспорта в ASP.NET

В заключение добавлю несколько слов об использовании паспорта в ASP.NET.
  • Указываем, что будем использовать идентификацию через паспорт. Для этого в web.config указываем .
  • Подключаем System.Web.Security.
  • Объявляем переменную private PassportIdentity myPassport;
  • В Page_Load инициализируем переменную myPassport. myPassport = (PassportIdentity ) (Page.User.Identity) ;
  • Далее выполняем все вызовы (FromNetworkServer, IsAuthenticated и т.д.), согласно описанию, приведенному выше.

 
     

   
   
     
  VBNet рекомендует