Java Web应用OpenID第1部分(RP实现)(2)

2019-01-19 16:14

5. 验证:RP 向 OP 请求用户名验证,并确保通信没有受到干扰。 6. 转到应用程序:身份验证之后,RP 为用户指向其先前请求的资源。 接下来,我们将详细分析这些步骤中的每一步,包括代码例子。在我们逐步查看下面内容时,我将从头到尾使用一个例子来阐述 OpenID 身份验证过程。 获取用户提供的标识符

这是 RP 应用程序的任务。在工作示例中,用户名是在应用程序的

OpenIdRegistrationPage 上获取的。我输入我的 OpenID 并单击 Confirm

OpenID 按钮。示例应用程序(充当 RP)现在知道我的用户提供标识符了。图 1 显示了运行中的示例应用程序的一幅截图。

图 1. 获取用户提供的标识符

在本例中,用户提供的标识符是 redneckyogi.myopenid.com。

UI 代码负责两项工作:确保用户在 Your OpenID 文本框中输入了文本,且在用户单击 Confirm OpenID 按钮时提交窗体。在确认之后,应用程序开始调用序列。清单 1 显示了 OpenIdRegistrationPage 中提交窗格和执行调用序列所用的代码。

清单 1. 使用 RegistrationService.java 执行 OpenID 身份验证调用序列的 Wicket UI 代码

Button confirmOpenIdButton = new Button(\ 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)); } };

试着不要受示例及其使用 Wicket UI 代码的方式困扰(不过如果您很好奇,完全可以查看 OpenIdRegistrationPage.java,也就是清单 1 的来源)。这里的重点是,当用户单击按钮时,UI 代码委托 RegistrationService 的各种方法来调用 openid4java 的 API,主要做三项工作(每一项都在清单 1 中用粗体表示): 1. 在用户提供的标识符上执行发现

2. 创建用于生成身份验证请求的 openid4java AuthRequest 对象 3. 重定向浏览器到 OpenID 提供者

重定向浏览器之后,UI 代码完成任务,现在控制权在 OP 手中。注意,

myopenid.com 是标识符的一部分,且用户提供的标识符不是结构良好的 URL。在标识符中仍然需要编码足够的信息,以允许 openid4java 规范化并执行发现。这将在下一部分介绍。 发现(discovery)

RP 采用用户提供的标识符,并将其转化为一种格式,可用于确定两个内容:OpenID 提供者(OP)是谁,如何联系 OP。

RP 使用发现过程来确定如何向 OP 发出请求,而关键便是用户提供的标识符。但是,在将用户提供的标识符用于发现之前,首先必须将其规范化。 openid4java 实际上已经承担了规范化用户提供标识符的工作,所以这里无需再作详细讨论。 两种不同的形式是:

1. XRI:可扩展资源标识符 2. URL:统一资源定位符

本文中我们将看一些 URL 示例。图 1 中的用户提供标识符是一个缺少模式的 URL,因此,作为规范化工作的一部分,openid4java 向其附加 “http://”,从而构成声明的标识符 http://redneckyogi.myopenid.com。

声明的标识符中的编码信息包含 OP 的名称,在本例中是 myOpenID。由于声明的标识符是一个 URL,openid4java 知道如何联系 OP — 在 http://myopenid.com上 — 这正是它所要做的。

清单 2(来自示例应用程序的 RegistrationService 类)显示 RP 如何使用 openid4java 执行发现。

清单 2. 使用 openid4java 执行发现 public static

DiscoveryInformation performDiscoveryOnUserSuppliedIdentifier( String userSuppliedIdentifier) {

DiscoveryInformation ret = null;

ConsumerManager consumerManager = getConsumerManager(); try {

// Perform discover on the User-Supplied Identifier List discoveries =

consumerManager.discover(userSuppliedIdentifier); // Pass the discoveries to the associate() method... ret = consumerManager.associate(discoveries); } catch (DiscoveryException e) {

String message = \ log.error(message, e);

throw new RuntimeException(message, e); }

return ret; }

openid4java 进行 OpenID 身份验证所用的核心类是 ConsumerManager。openid4java 对于该类的使用有严格的准则。它将该类作为静态类成员存储并通过 getConsumerManager() 方法予以访问(参见示例应用程序中的 RegistrationService.java 了解更多信息)。

openid4java 允许使用一行代码(清单 2 中粗体部分)规范化用户提供的标识符并执行发现。返回的是 DiscoveryInformation 对象的 java.util.List。可将这些对象看作不透明对象。一定要保留这些对象,因为当您的 RP 实现选择构建与 OP 的关联时,要用到它们(如示例应用程序)。 关联

关联是 RP 和 OP 建立共享密钥(通过 Diffie-Hellman 密钥交换)的一种方式,能使它们之间的交互更安全可信。关联不是 OpenID 规范所必需的。关联是从 RP 代码中执行的,仅需调用 ConsumerManager 上的 associate() 方法即可,如清单 3 所示。

清单 3. 使用 openid4java 建立关联

public static

DiscoveryInformation performDiscoveryOnUserSuppliedIdentifier( String userSuppliedIdentifier) {

DiscoveryInformation ret = null;

ConsumerManager consumerManager = getConsumerManager(); try {

// Perform discover on the User-Supplied Identifier List discoveries =

consumerManager.discover(userSuppliedIdentifier); // Pass the discoveries to the associate() method... ret = consumerManager.associate(discoveries); } catch (DiscoveryException e) {

String message = \ log.error(message, e);

throw new RuntimeException(message, e); }

return ret; }

这种方法返回 DiscoveryInformation 对象,它用来描述发现的结果(您可将该对象看作不透明对象)。示例应用程序存储一个 session 中的

DiscoveryInformation 对象,因为稍后会用到该对象。要发出身份验证请求,就需要该对象,接下来我们将对此进行讨论。 身份验证

RP 在用户提供的标识符上成功执行发现后,该到验证用户身份的时候了。ConsumerManager 需要建立一个称作 AuthRequest 的特殊对象,OP 会使用该对象处理身份验证请求。

在此次交互中,需要利用名为 SimpleRegistration(简称 SReg)的一个 OpenID 扩展;该扩展允许 RP 提出以下请求:在响应中返回 OP 用户资料中的某些属性。清单 4 显示了建立 AuthRequest 对象和使用 SReg 请求属性的代码。

清单 4. 建立 AuthRequest 并使用 SReg 扩展 public static AuthRequest

createOpenIdAuthRequest(DiscoveryInformation discoveryInformation, String returnToUrl) { AuthRequest ret = null; // try {

// Create the AuthRequest object ret =

getConsumerManager().authenticate(discoveryInformation, returnToUrl);

// Create the Simple Registration Request SRegRequest sRegRequest =

SRegRequest.createFetchRequest();

sRegRequest.addAttribute(\ sRegRequest.addAttribute(\ sRegRequest.addAttribute(\

sRegRequest.addAttribute(\ret.addExtension(sRegRequest); } catch (Exception e) {

String message = \ \ log.error(message, e);

throw new RuntimeException(message, e); }

return ret; }


Java Web应用OpenID第1部分(RP实现)(2).doc 将本文的Word文档下载到电脑 下载失败或者文档不完整,请联系客服人员解决!

下一篇:java面试题1

相关阅读
本类排行
× 注册会员免费下载(下载后可以自由复制和排版)

马上注册会员

注:下载文档有可能“只有目录或者内容不全”等情况,请下载之前注意辨别,如果您已付费且无法下载或内容有问题,请联系我们协助你处理。
微信: QQ: