OpenID в Web-приложениях на Java: Часть 1. Аутентификация при помощи OpenID в вашем Web-приложении

OpenID – это децентрализованный протокол, облегчающий пользователям доступ к ресурсам вашего Web-приложения. В этой статье, первой в серии из двух частей, вы познакомитесь со спецификацией аутентификации OpenID и узнаете, как добавить ее поддержку в Java-приложение. Вместо самостоятельной реализации спецификации в статье демонстрируется использование библиотеки openid4java и myOpenID (популярного провайдера OpenID) в целях реализации безопасного и надежного процесса регистрации для приложения на основе Wicket.

Дж. Стивен Перри, главный консультант, Makoto Consulting Group, Inc.

Photo of J Steven PerryДж. Стивен Перри (J. Steven Perry) – независимый консультант по вопросам разработки программного обеспечения, профессионально занимающийся созданием ПО с 1991 г. Стив увлекается программированием, получает удовольствие от написания статей и книг на эту тему, а также от консультирования других разработчиков. Он является автором книг Java Management Extensions и Log4j (обе книги выпущены издательством O'Reilly) и статьи Время Йоды, опубликованной на сайте IBM developerWorks. Свое свободное время он проводит с тремя детьми, катается на велосипеде и преподает йогу. Стив является владельцем и главным консультантом компании Makoto Consulting Group, расположенной в городе Литтл Рок, штат Арканзас.



25.10.2010

OpenID – это децентрализованный механизм аутентификации. С его помощью я могу подтвердить, что являюсь владельцем URI, например http://openid.jstevenperry.com/steve, и могу его использовать для аутентификации на любом сайте, поддерживающем OpenID, таком, как Google, Slashdot или Wordpress. Преимущества OpenID для конечных пользователей совершенно очевидны. Однако в процессе работы с ним я задался вопросом: не использовать ли OpenID для реализации надежной системы аутентификации для Web-приложений на Java, которые я разрабатываю для своих заказчиков?

В этой серии из двух статей демонстрируется использование библиотеки openid4java и широко известного провайдера OpenID, myOpenID, для создания системы аутентификации для Web-приложения, написанного на Java. Вы также узнаете о получении пользовательской информации при помощи расширения SReg (OpenID Simple Registration Extension). 

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

На протяжении всей статьи мы будем работать с Web-приложением на основе Wicket, которое было создано специально для этой серии. Ссылка на архив с исходным кодом находится в разделе Загрузка. Кроме того, обратите внимание на библиотеку openid4java  (см. раздел Ресурсы).

Замечание. Эта статья посвящена использованию OpenID в Web-приложениях, написанных на Java, однако OpenID может применяться для любых приложений.

Введение в OpenID

OpenID – это спецификация, описывающая, как пользователь может доказать, что является владельцем того или иного идентификатора. Для простоты можно считать, что идентификатор – это строка, которая уникальным образом идентифицирует пользователя. Возможно, что у вас, как и у меня, есть несколько идентификаторов (userid). Например, у меня есть одно имя пользователя в Facebook, другое – в Twitter, а также с десяток других, которые я использую на разных сайтах в Интернете. При этом я всегда стараюсь использовать одно и то же имя, но оно часто бывает занято при регистрации на новом сайте. Таким образом, приходится поддерживать в памяти некую карту имен, ассоциированных с соответствующими Web-сайтами. Это доставляет множество неудобств, и мне приходится часто использовать функцию "Забыли свое имя пользователя?". Было бы гораздо лучше, если бы я мог использовать один идентификатор на всех ресурсах.

OpenID решает именно эту задачу. Благодаря OpenID я могу завести один идентификатор и использовать его на всех сайтах, которые поддерживают этот протокол. По последним данным с сайта OpenID, он поддерживается более чем 50000 сайтами, среди которых Facebook, Yahoo!, Google и Twitter.

Аутентификация при помощи OpenID

Центральное место в OpenID занимает аутентификация, которая включает в себя три ключевых понятия:

  • идентификатор OpenID: строка, которая уникально идентифицирует пользователя;
  • клиент OpenID (OpenID Relying Party или RP): online-ресурс (чаще всего Web-сайт, но им также может быть файл, изображение или любой ресурс, к которому необходимо контролировать доступ), который использует OpenID для идентификации обращающихся к нему пользователей;
  • провайдер OpenID (OP): сайт, на котором пользователи могут завести OpenID и который может в будущем авторизовывать и аутентифицировать пользователей, обращающихся к RP.

OpenID Foundation - это консорциум, члены которого заинтересованы в продвижении открытой системы аутентификации пользователей на основе спецификации OpenID.

Принципы работы OpenID

Представьте, что некий пользователь пытается получить доступ к ресурсу, который является частью Web-сайта RP, поддерживающего OpenID. Для обращения к ресурсу пользователь должен предъявить свой идентификатор OpenID в той форме, которая позволяет распознать в нем протокол OpenID. В частности, идентификатор OpenID указывает на местоположение OP. Таким образом, RP извлекает идентификатор и перенаправляет пользователя на сайт OP, где он должен будет подтвердить, что является владельцем данного идентификатора.

Далее мы кратко рассмотрим каждый из компонентов спецификации OpenID, а также роли, которые они играют в процессе аутентификации.

Идентификаторы OpenID

Сердцем OpenID является, разумеется, идентификатор OpenID. Идентификатор OpenID (или просто "идентификатор") - это удобочитаемая символьная строка, уникальным образом идентифицирующая пользователя. Один идентификатор не может принадлежать более чем одному пользователю. Клиентские сайты OpenID декодируют (нормализуют) идентификаторы, следуя инструкциям в cпецификации аутентификации OpenID, версия 2.0, чтобы определить, как следует аутентифицировать конкретного пользователя. С точки зрения разработчиков ПО, следует различать следующие два вида идентификаторов:

  • идентификатор, предъявленный пользователем (User Supplied Identifier);
  • заявленный идентификатор (Claimed Identifier).

Как следует из названия, идентификатор, предъявленный пользователем - это строка, которая была получена RP от пользователя. Этот идентификатор следует нормализовать, т.е. преобразовать к виду заявленного идентификатора. Заявленный идентификатор может затем использоваться для нахождения OP (этот процесс называется "обнаружением провайдера"), который должен будет аутентифицировать пользователя.

Клиенты OpenID (RP)

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

RP ничего не знает о деталях аутентификации по заявленным идентификаторам. Все, что его интересует – это результат аутентификации (положительный или отрицательный). Если аутентификация прошла успешно, то пользователь возвращается к защищенному ресурсу, к которому он изначально пытался получить доступ. В противном случае RP отказывает в доступе к ресурсу.

Провайдеры OpenID (OP)

Провайдеры OpenID отвечают за выделение идентификаторов и выполнение аутентификации. Они также предоставляют Web-интерфейс для управления выданными идентификаторами. OP собирают и хранят следующую информацию о каждом пользователе:

  • адрес e-mail;
  • полное имя;
  • дату рождения;
  • почтовый индекс;
  • страну проживания;
  • основный язык;

При запросе на аутентификацию по заявленному идентификатору OP перенаправляет пользователя на страницу авторизации, которая запрашивает его имя и пароль. В этот момент процесс аутентификации полностью переходит к OP. Если пользователь успешно аутентифицировался, OP перенаправляет его браузер по адресу, указанному RP ("return-to" URL). В противном случае пользователь должен получить сообщение, что попытка аутентификации окончилась неудачно (по крайней мере, так поступают ClaimID и myOpenID – два популярных провайдера OpenID).

Как стать клиентом OpenID

Итак, вы уже знаете об основных компонентах OpenID и их взаимодействии друг с другом. Далее мы рассмотрим создание клиентов OpenID (RP) с использованием открытой библиотеки openid4java.

Вначале необходимо получить идентификатор. Нет ничего проще: зайдите на сайт myOpenID и нажмите на кнопку SIGN UP FOR AN OPENID. Выберите себе имя наподобие redneckyogi или jstevenperry (оба этих имени принадлежат мне), после чего форма ввода должна вам сказать, свободно выбранное имя или нет. Если свободно, то вам останется только ввести пароль, адрес e-mail и ряд символов под контрольным изображением (чтобы отличить вас от программы-агента).

Через несколько минут на указанный почтовый ящик вы должны получить письмо со ссылкой. Нажмите на ссылку для подтверждения адреса e-mail, после чего вы станете счастливым обладателем идентификатора OpenID.

Разумеется, как это часто бывает в случае модных технологий, вы можете выбирать из множества провайдеров OpenID (полный список приведен по ссылке в разделе Ресурсы).

Чтобы убедиться, в легкости получения OpenID, я завел учетные записи на сайтах провайдеров myOpenID, Verisign и ClaimID, причем это заняло у меня не более 30 минут. При этом за эти 30 минут я также успел ввести подробную информацию о себе и даже загрузить фотографию!

У вас уже может быть OpenID

По данным OpenId.net, Google, Wordpress и другие популярные ресурсы поддерживают OpenID, поэтому если вы на них зарегистрированы, что вполне вероятно, то вы уже являетесь владельцем идентификатора OpenID.

Например, если у вас есть учетная запись Yahoo!, то скорее всего у вас есть OpenID (у меня был такой OpenID, о котором я даже не подозревал). Вы можете использовать свой Yahoo! ID для аутентификации на других ресурсах, и Yahoo! будет выступать в качестве вашего OP. Другими словами, вы можете ввести ваш идентификатор вида whatever@yahoo.com, после чего RP попросит Yahoo! аутентифицировать вас (вы можете убедиться в этом, запустив демонстрационное приложение к этой статье).

Демонстрационное приложение

Как упоминалось выше, демонстрационное приложение к этой статье – это Web-приложение, написанное на Java, которое представляет собой простой клиент (RP), использующий библиотеку openid4java. Вы можете собрать это приложение в виде архива WAR, скопировать его в директорию Tomcat и запустить на вашем локальном компьютере. Приложение демонстрирует следующее:

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

Я создал это приложение на основе Wicket просто потому, что мне нравится эта технология. При этом я постарался минимизировать влияние Wicket, чтобы она не отвлекала вас от базовых вопросов создания RP.

C точки зрения архитектуры, приложение включает в себя два основных компонента:

  • интерфейс пользователя, написанный на Wicket;
  • аутентификацию при помощи OpenID, реализованную при помощи библиотеки openid4java.

Разумеется, эти компоненты частично накладываются друг на друга, но я старался свести их взаимодействие к минимуму, чтобы вам было легче усвоить принципы OpenID, не отвлекаясь на детали работы с Wicket.

Библиотека openid4java и код демонстрационного приложения

Спецификация процесса аутентификации OpenID достаточно сложна. Если у вас есть обширный опыт реализации спецификаций, то, вероятно, вам не составит труда реализовать и аутентификацию по OpenID. Однако если вы так же ленивы, как и я, и предпочитаете готовую реализацию, которую можно применять при решении конкретной задачи, то вам пригодится библиотека openid4java. Она полностью реализует спецификацию, значительно облегчая работу с ней программным образом.

Ниже будут рассмотрены примеры кода RP, в которых используются вызовы методов API openid4java для работы с OpenID. Обратите внимание на малый объем требующегося кода, что говорит о том, насколько openid4java облегчает жизнь разработчикам.

Для того чтобы уменьшить зависимость приложения от Wicket я вынес код, в котором происходит обращение к openid4java, в отдельный Java-класс с именем RegistrationService (пакет com.makotogroup.sample.model). Этот класс содержит пять методов, выполняющих обособленные задачи с использованием API openid4java:

  • getReturnToUrl() возвращает URL, по которому должен быть перенаправлен пользователь после успешной аутентификации;
  • getConsumerManager() используется для получения экземпляра на главный класс openid4java. Этот класс предоставляет все методы, которые требуются демонстрационному приложению для аутентификации пользователей;
  • performDiscoveryOnUserSuppliedIdentifier() обрабатывает все нештатные ситуации, которые могут возникнуть в процессе обнаружения провайдера OpenID;
  • createOpenIdAuthRequest() создает структуру данных AuthRequest, необходимую для аутентификации;
  • processReturn() занимается обработкой результатов запроса на аутентификацию.

Реализация RP

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

Демонстрационное приложение использует стандартный в настоящее время механизм, основанный на регистрации пользователей. С точки зрения приложения, если пользователь идентифицирован, то ему будет позволено зарегистрироваться. Это довольно простое условие, но его достаточно, чтобы продемонстрировать типичный "диалог" между приложением и OP, а также использующиеся для этого средства openid4java. Диалог заключается в выполнении следующих действий:

  1. Получение идентификатора, предъявленного пользователем: RP получает OpenID от пользователя.
  2. Обнаружение: RP нормализует предъявленный пользователем идентификатор для определения того, какой OP должен выполнять аутентификацию и где он находится.
  3. Связывание: не обязательное, но рекомендуемое действие: RP и OP устанавливают безопасный канал связи.
  4. Запрос на аутентификацию: RP обращается к OP с просьбой об аутентификации пользователя.
  5. Проверка: RP запрашивает проверку идентификатора пользователя, чтобы убедиться, что канал связи не был скомпрометирован третьей стороной.
  6. Возврат к приложению: после аутентификации RP перенаправляет пользователя к изначально запрошенному ресурсу.

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

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

Это действие является одной из функций вашего приложения. В нашем случае идентификатор запрашивается на странице OpenIdRegistrationPage. На ней следует ввести OpenID и нажать на кнопку Confirm OpenID. После этого приложение, выступающее в роли RP, может выполнять необходимые действия с предъявленным идентификатором. Снимок экрана с интерфейсом приложения показан на рисунке 1.

Рисунок 1. Предъявление идентификатора пользователем
A screen shot of the sample application in action.

В данном случае предъявленным идентификатором является redneckyogi.myopenid.com.

Код интерфейса выполняет две функции: во-первых, он проверяет, что пользователь ввел значение в текстовое поле Your OpenID, а во-вторых, отправляет форму при нажатии на кнопку Confirm OpenID. После этого приложение выполняет серию вызовов методов. В листинге 1 приведен фрагмент кода, выполняющегося в момент отправки формы на сервер.

Листинг 1. Код Wicket, выполняющий серию вызовов методов для аутентификации по OpenID при помощи класса RegistrationService
Button confirmOpenIdButton = new Button("confirmOpenIdButton") {
  public void onSubmit() {
    String userSuppliedIdentifier = formModel.getOpenId();
   DiscoveryInformation discoveryInformation = 
RegistrationService.performDiscoveryOnUserSuppliedIdentifier(
        userSuppliedIdentifier);
    MakotoOpenIdAwareSession session =
     (MakotoOpenIdAwareSession)owningPage.getSession();
    session.setDiscoveryInformation(discoveryInformation, true);
    AuthRequest authRequest =
      RegistrationService.createOpenIdAuthRequest(
        discoveryInformation, returnToUrl);
    getRequestCycle().setRedirect(false);
   getResponse().redirect(authRequest.getDestinationUrl(true));
    }
};

Постарайтесь не обращать слишком много внимания на использование Wicker (если вас это интересует, то ознакомьтесь с полной версией кода в файле OpenIdRegistrationPage.java). Самое главное в этом листинге - это вызовы различных методов класса RegistrationService, которые работают с API openid4java. Эти методы, выделенные жирным шрифтом, выполняют следующие действия.

  1. Поиск провайдера по идентификатору.
  2. Создают объект AuthRequestПеренаправляют пользователя на сайт провайдера OpenID.
  3. перенаправляют пользователя на сайт провайдера OpenID.

После перенаправления браузера на сайт провайдера управление передается OP. Обратите внимание, что myopenid.com является частью идентификатора, а сам предъявленный пользователем идентификатор не является синтаксически корректным URL. Тем не менее, он содержит достаточно информации, чтобы openid4java смогла обнаружить сайт провайдера. Этот процесс рассматривается в следующем разделе.

Обнаружение

RP выполняет преобразование предъявленного пользователем идентификатора в форму, которая позволяет определить две вещи: провайдера OpenID (OP) и способ обращения к нему.

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

Идентификатор может быть представлен в двух основных формах.

  1. XRI (Extensible Resource Identifier): расширяемый идентификатор ресурса.
  2. URL (Uniform Resource Locator): универсальный идентификатор ресурса.

В этой статье мы будем работать с URL. Идентификатор на рисунке 1 представляет собой URI, но без схемы, поэтому в процессе нормализации openid4java добавляет префикс "http://". В результате получается заявленный идентификатор вида http://redneckyogi.myopenid.com.

Заявленный идентификатор включает имя провайдера, в данном случае myOpenID. Он имеет вид URL, который библиотека openid4java может использовать для обращения к OP (т.е. по адресу http://myopenid.com).

В листинге 2 приведен фрагмент кода класса RegistrationService, демонстрирующий обнаружение провайдера при помощи openid4java.

Листинг 2. Обнаружение провайдера при помощи openid4java
public static
   DiscoveryInformation performDiscoveryOnUserSuppliedIdentifier(
      String userSuppliedIdentifier) {
	
  DiscoveryInformation ret = null;
  ConsumerManager consumerManager = getConsumerManager();
  try {
    // Обнаружение провайдера по предъявленному пользователем идентификатору
   List<DiscoveryInformation> discoveries =
      consumerManager.discover(userSuppliedIdentifier);
    // Передача объектов DiscoverInformation в метод associate()...
    ret = consumerManager.associate(discoveries);
  } catch (DiscoveryException e) {
    String message = "Error occurred during discovery!";
    log.error(message, e);
    throw new RuntimeException(message, e);
  }
  return ret;
}

Центральным классом openid4java, отвечающим за аутентификацию, является ConsumerManager. openid4java предлагает строгие инструкции насчет использования этого класса. Он имеет единственный статический экземпляр, обращение к которому должно происходить через метод getConsumerManager() (если вас интересуют детали, обратитесь к классу RegistrationService.java в демонстрационном приложении).

Нормализация предъявленного пользователем идентификатора и обнаружение провайдера выполняются в единственной строке кода, выделенной жирным шрифтом в листинге 2. В этой строке openid4java возвращает список объектов типа DiscoveryInformation. Их вполне можно рассматривать как своего рода "черные ящики", которые могут понадобиться, если ваш RP должен устанавливать безопасное соединение с провайдером (именно это делает демонстрационное приложение).

Связывание

Связывание необходимо для установления безопасного соединения между RP и OP (при помощи протокола Диффи-Хеллмана) для защиты взаимодействия. С точки зрения спецификации OpenID, связывание не является обязательной операцией. Она выполняется на стороне RP при помощи единственного вызова метода associate() класса ConsumerManager, как показано в листинге 3.

Листинг 3. Безопасное взаимодействие с провайдером при помощи openid4java
public static 
   DiscoveryInformation performDiscoveryOnUserSuppliedIdentifier(
      String userSuppliedIdentifier) {
	
  DiscoveryInformation ret = null;
  ConsumerManager consumerManager = getConsumerManager();
  try {
    // Обнаружение провайдера по предъявленному пользователем идентификатору
    List<DiscoveryInformation> discoveries =
      consumerManager.discover(userSuppliedIdentifier);
    // Передача объектов DiscoverInformation в метод associate()...
    ret = consumerManager.associate(discoveries);
  } catch (DiscoveryException e) {
    String message = "Error occurred during discovery!";
    log.error(message, e);
    throw new RuntimeException(message, e);
  }
  return ret;
}

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

Аутентификация

После успешного обнаружения провайдера, указанного в предъявленном пользователем идентификаторе, необходимо выполнить саму аутентификацию. Для этого объект типа ConsumerManager должен создать специальный объект AuthRequest, который будет использоваться провайдером в процессе аутентификации.

В процессе этого взаимодействия от провайдера потребуется использовать расширение OpenID под названием SimpleRegistration (или SReg) для передачи определенных атрибутов из профиля пользователя RP-приложению. В листинге 4 показан фрагмент кода для создания объекта AuthRequest и запроса на получение атрибутов пользователя при помощи SReg.

Листинг 4. Создание объекта AuthRequest и использование расширения SReg
public static AuthRequest 
createOpenIdAuthRequest(DiscoveryInformation 
discoveryInformation, String returnToUrl) {
  AuthRequest ret = null;
  //
  try {
    // Создание объекта AuthRequest
   ret =getConsumerManager().authenticate(discoveryInformation,
                                            returnToUrl);
    // Создание запроса при помощи расширения SReg  
SRegRequest sRegRequest = 
SRegRequest.createFetchRequest();
    sRegRequest.addAttribute("email", false);
    sRegRequest.addAttribute("fullname", false);
    sRegRequest.addAttribute("dob", false);
    sRegRequest.addAttribute("postcode", false);
    ret.addExtension(sRegRequest);
  } catch (Exception e) {
    String message = "Exception occurred while building " +
                     "AuthRequest object!";
    log.error(message, e);
    throw new RuntimeException(message, e);
  }
  return ret;
}

В первой строке, выделенной жирным шрифтом в листинге 4, показан вызов метода ConsumerManager.authenticate(), который на самом деле не выполняет запрос на аутентификацию. Он принимает на вход объект DiscoveryInformation, полученный в процессе обнаружения провайдера (см. листинг 3), а также URL, по которому должен быть перенаправлен пользователь после успешного выполнения аутентификации.

Во второй строке, выделенной жирным шрифтом, показано создание запроса SReg при помощи статического метода SRegRequest.createFetchRequest(). После этого атрибуты, которые должны быть получены от провайдера через расширение SReg, запрашиваются путем вызовов метода addAttribute() объекта SRegRequest. Наконец, расширение добавляется в объект AuthRequest при помощи метода addExtension().

Библиотека openid4java выполняет все эти действия интуитивно понятным образом. К этому моменту браузер уже перенаправлен на сайт провайдера, отвечающего за аутентификацию, на котором пользователь должен ввести свое имя и пароль. Перенаправление выполняется классом OpenIdRegistrationPage.java, который является частью Wicket-интерфейса приложения. На рисунке 2 показан снимок экрана со страницей аутентификации на сайте myOpenID.

Рисунок 2. Запрос на аутентификацию к провайдеру myOpenID
A screen shot of the myOpenID server authenticating a request.

На этом этапе у вас уже должен быть готов обработчик запросов по URL, который вы указали в параметре "return-to" (см. листинг 4). В демонстрационном приложении этот URL жестко указан в методе RegistrationService.getReturnToUrl(). Конструктор класса OpenIdRegistrationSavePage разбирает запрос, выясняя, получен ли тот от провайдера OpenID. Если да, то его содержимое должно пройти проверку.

Проверка

В листинге 5 показан фрагмент кода, который проверяет, действительно ли запрос получен от OP. Если да, то значением параметра is_return должно быть true. В этом случае библиотека openid4java должна проверить запрос (который, по сути, является откликом провайдера) и извлечь из него атрибуты, которые были запрошены в листинге 4.

Листинг 5. Использование параметра return-to
public OpenIdRegistrationSavePage(PageParameters pageParameters) {
  RegistrationModel registrationModel = new RegistrationModel();
  if (!pageParameters.isEmpty()) {
    String isReturn = pageParameters.getString("is_return");
    if (isReturn.equals("true")) {
      MakotoOpenIdAwareSession session = 
        MakotoOpenIdAwareSession)getSession();
      DiscoveryInformation discoveryInformation =
        session.getDiscoveryInformation();
      registrationModel = 
        RegistrationService.processReturn(discoveryInformation,
          pageParameters, 
          RegistrationService.getReturnToUrl());
      if (registrationModel == null) {
          error("Open ID Confirmation Failed.");
        }
      }
    }
    add(new OpenIdRegistrationInformationDisplayForm("form",
        registrationModel));
  }

В этом фрагменте кода конструктор страницы Wicket сначала определяет, что запрос представляет собой отклик провайдера на ранее выполненный запрос на аутентификацию. Далее он извлекает объект типа DiscoveryInformation, сохраненный после обнаружения провайдера, при помощи класса MakotoOpenIdAwareSession (специальной реализации Session). Этот объект передается в метод RegistrationService.processReturn(), отвечающий за проверку запроса. Кроме того, в проверке используются параметры запроса и URL "return-to". При положительном результате проверки возвращается полностью заполненный объект типа RegistrationModel. Он может выступать в роли Wicket-модели для страницы OpenIdRegistrationSavePage, которая может выполнять любую необходимую приложению функцию.

Возврат к приложению

Если отклик провайдера на запрос аутентификации успешно проверен, пользователю предоставляется доступ к ресурсу RP, защищенному при помощи OpenID. В случае демонстрационного приложения таковым ресурсом является процесс регистрации. Успешно аутентифицированный пользователь перенаправляется на страницу, на которой он или она может просмотреть информацию о себе, полученную от OP, отредактировать ее и сохранить. Наше приложение пока не содержит кода для сохранения информации, но вы его можете легко добавить самостоятельно. На рисунке 3 показана страница с информацией, полученной от провайдера, в ответ на запрос моей аутентификации через OpenID.

Рисунок 3. Отображение информации из профиля пользователя на сайте OP в демонстрационном приложении
Screen shot showing information pulled from the OpenID Provider for authentication purposes.

Заключение

OpenID решает проблему управления множеством имен для аутентификации на различных ресурсах, причем его популярность неуклонно возрастает. Получить собственный идентификатор OpenID не составляет никакого труда, чем воспользовались миллионы пользователей. Подобно любой спецификации, "Аутентификация OpenID" достаточно сложна, но в ее использовании нет ничего сложного благодаря библиотеке openid4java. В этой статье рассказывалось о принципах работы OpenID. Кроме того, было продемонстрировано, насколько легко процесс аутентификации может быть встроен в Web-приложение, написанное на Java.

Следующая статья этой серии будет посвящена другому аспекту OpenID: написанию собственного провайдера. Основные моменты в ней также будут объясняться на примерах, включающих в себя пару специально созданных Web-приложений. До тех пор вы можете свободно упражняться в использовании кода класса RegistrationService в целях реализации процесса аутентификации в ваших собственных приложениях.


Загрузка

ОписаниеИмяРазмер
Примеры работы с OpenIDopenid4java-sample-app.zip4.3 MБ

Ресурсы

Научиться

Получить продукты и технологии

Комментарии

developerWorks: Войти

Обязательные поля отмечены звездочкой (*).


Нужен IBM ID?
Забыли Ваш IBM ID?


Забыли Ваш пароль?
Изменить пароль

Нажимая Отправить, Вы принимаете Условия использования developerWorks.

 


Профиль создается, когда вы первый раз заходите в developerWorks. Информация в вашем профиле (имя, страна / регион, название компании) отображается для всех пользователей и будет сопровождать любой опубликованный вами контент пока вы специально не укажите скрыть название вашей компании. Вы можете обновить ваш IBM аккаунт в любое время.

Вся введенная информация защищена.

Выберите имя, которое будет отображаться на экране



При первом входе в developerWorks для Вас будет создан профиль и Вам нужно будет выбрать Отображаемое имя. Оно будет выводиться рядом с контентом, опубликованным Вами в developerWorks.

Отображаемое имя должно иметь длину от 3 символов до 31 символа. Ваше Имя в системе должно быть уникальным. В качестве имени по соображениям приватности нельзя использовать контактный e-mail.

Обязательные поля отмечены звездочкой (*).

(Отображаемое имя должно иметь длину от 3 символов до 31 символа.)

Нажимая Отправить, Вы принимаете Условия использования developerWorks.

 


Вся введенная информация защищена.


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=40
Zone=Технология Java, Open source
ArticleID=556034
ArticleTitle=OpenID в Web-приложениях на Java: Часть 1. Аутентификация при помощи OpenID в вашем Web-приложении
publish-date=10252010