《Spring Security3》第八章第一部分翻译(OpenID与Spring Security)
第八章 对OpenID开放
OpenID是很流行的可信任身份管理方式,它允许用户通过一个单独的可信任提供者(provider)管理其身份信息。这个便利的功能为用户提供了安全的方式即使用可信任的OpenID提供者来存储器密码和个人信息,并可以随意的基于请求获取其个人信息。另外,启用OpenID功能的站点能够确信用户提供的OpenID凭证信息就是他们所说的人。
在本章中,我们将会:
l 学习在五分钟之内建立自己的OpenID;
l 使用快速实现的OpenID来配置JBCP Pets站点;
l 学习OpenID的概念架构以及它怎样为你的站点提供可信任的用户访问;
l 实现基于OpenID的用户注册;
l 体验OpenID属性交换得到用户简介功能;
l 检查基于OpenID登录的安全性。
OpenID承诺的世界
作为一项技术,OpenID的承诺是允许web上的用户通过一个可信任的提供者集中管理他们的个人数据和信息,然后这个可信任的提供者作为代理与用户想交互的站点建立起互信。
概念上来说,这种类型的登录要通过一个长时间存在的可信任第三方,可以有多种方式(如Microsoft Passport,曾经是最知名的中心登录服务)。OpenID的区别优势在于OpenID提供者(OpenID Provider)仅仅需要实现一个协议,这个协议与任何试图通过OpenID进行集成登录的站点相协调。OpenID规范本身也是一个开放的规范,这就导致出现了不同的提供者但运行相同的协议。这对健康竞争是一种好事,也有利于客户的选择。
下图整体说明了一个集成OpenID的站点在登录过程中与OpenID提供者之间的关系:
我们可以看到用户以唯一名字标识的方式提供自己的凭证信息,一般是统一资源标识符(Uniform Resource Identifier,URI),这是OpenID提供者分配给用户的,用来唯一标识用户和OpenID提供者。这通常是OpenID提供者URI的子域名(如:https://jamesgosling.myopenid.
com/),或者在OpenID提供者URI上添加唯一标识(如:https://me.yahoo.com/jamesgosling)。我们可以看到这两种方式的URL都能很明确的标识出OpenID提供者(通过域名)和唯一的用户标识。
【不要不加考虑地信任OpenID。在这里你看到我们可以伪装系统中的用户。我们可以用一个OpenID登录,它可能会以为我们是James Gosling,当然我们不是。不要做这样错误的假设,即因为有一个听起来令人信服的OpenID(或OpenID代理提供者)那他们就是认证过的人了,而不需要额外方式的认证。以另外的方式想一下这个问题,如果有个人敲你的门并说自己是James Gosling,你会不检查他的ID就让他进来吗?】
启用OpenID的应用接下来会重定向到OpenID提供者哪里,在这里用户提供他的认证信息,OpenID提供者负责做出访问决定(译者注:即登录是否成功)。一旦提供者做出访问决定,它将用户重定向会原始的站点,这是可以确信用户的真实性了。
如果你开始进行尝试,那OpenID就更容易理解了。让我们添加OpenID到JBCP Pets登录页上。
注册一个OpenID
为了完全体现本节中这个练习的价值(并测试登录),你需要在众多可用的OpenID中选择一个拥有自己的OpenID,他们的列表可以在这里看到:http://openid.net/get-an-openid/。有些通用的OpenID提供者,你可能已经有它们的账号了如Yahoo!,AOL, Flickr或MySpace。Google的OpenID支持略有不同,在本章后面的添加Sign In with Google到登录页时,我们将会看到。为了完整的完成本章的练习,我们建议你最少有以下的账号:
l myOpenID
l Google
使用Spring Security启用OpenID认证
在接下来的几章介绍外部认证提供者时,我们将会看到一个通用的模式。关于与Spring系统之外的提供者集成,Spring Security提供了便利的包装。
在这里,openid4java项目(http://code.google.com/p/openid4java/)为Spring Security的OpenID功能提供了底层OpenID提供者发现和请求/响应握手(negotiation)的功能。
编写一个OpenID登录表单
常见的方式是站点在一个登录页上提供了标准(用户名和密码)和OpenID两种登录选择,允许用户在两种方式中选择,JBCP Pets的最终登录页如下:
基于OpenID的form代码如下:
<h1>Or, Log Into Your Account with OpenID</h1> <p> Please use the form below to log into your account with OpenID. </p> <form action="j_spring_openid_security_check" method="post"> <label for="openid_identifier">Login</label>: <input id="openid_identifier" name="openid_identifier" size="20" maxlength="100" type="text"/> <img src="images/openid.png" alt="OpenID"/> <br /> <input type="submit" value="Login"/> </form>
Form域的名字即openid_identifier是有特定含义的。OpenID规范建议使用的站点以这个名字作为OpenID登录域,所以用户客户端(浏览器)对于这个域的功能也具有语义理解。甚至有浏览器插件如Verisign's OpenID SeatBelt (https://pip.verisignlabs.com/seatbelt.do),它能够利用这个语义理解,预先在识别的页面把OpenID凭证填入OpenID域中。
你可能会意识到在OpenID登录中没有提供remember me选项。这是因为从重定向到提供者再回来,导致remember me复选框的值丢失,所以当用户登录成功后,他们不再有remember me选项。这很遗憾,但是这却增强了我们OpenID登录机制的安全性,因为OpenID强制用户每次登录时都与提供者建立可信任的关系。
在Spring Security中配置支持OpenID
回到基本的OpenID,它包括一个servlet过滤器和认证提供者,只要在dogstore-security.xml文件中的<http>配置元素中添加一个指令即可:
<http auto-config="true" ...> <!-- Omitting content... --> <openid-login/> </http>
在添加完这个配置元素后并重启应用,你可以重启应用,你能够使用OpenID登录form提供OpenID并会执行OpenID认证流程。但是当你回到JBCP Pets,你会被拒绝访问。这是因为你的凭证并没有任何角色。接下来,我们要处理它。
添加OpenID用户
因为现在我们还没有使用OpenID的新用户注册,所以需要手动的插入用户账号(测试所用)到数据库中,这是通过添加到test-users-groups-data.sql数据库启动代码中做到的。我们推荐在这一步你使用myOpenID(注意,如果使用Yahoo!会有问题,原因我们下面介绍)。假设我们的OpenID是https://jamesgosling.myopenid.com/,那要插入这个文件的SQL如下:
insert into users(username, password, enabled, salt) values ('https://jamesgosling.myopenid.com/','unused',true,CAST(RAND()*1000000000 AS varchar)); insert into group_members(group_id, username) select id,'https://jamesgosling.myopenid.com/' from groups where group_name='Administrators';
你可能会发现这与我们插入传统的基于用户名和密码的admin账号很类似,只是我们使用“unused”作为密码。我们这样做,当然是因为基于OpenID的登录并不需要我们的站点存储用户的密码。但是,细心的读者可能会发现,这并不允许用户创建一个任意的用户名和密码并将其与OpenID关联——我们将会在本章后面简单介绍这个过程,你也可以作为使用这项技术的高级用法,自己探索如何实现。
此时,你可以完成使用OpenID实现完整登录。重定向的顺序通过以下的截图以箭头的方式进行了描述:
现在我们有了使用OpenID的JBCP Pets登录!可以测试多个OpenID提供者。你会发现,尽管整体的功能是一样的,但是不同提供者的检查和接受OpenID的体验是不同。
推荐阅读
-
《Spring Security3》第六章第二部分翻译(自定义AuthenticationProvider)
-
《Spring Security3》第六章第四部分翻译(异常处理)
-
《Spring Security3》第四章第三部分翻译上(配置安全的密码)
-
《Spring Security3》第一章第一部分翻译
-
《Spring Security3》第六章第二部分翻译(自定义AuthenticationProvider)
-
《Spring Security3》第四章第三部分翻译下(密码加salt)
-
《Spring Security3》第二章第一部分翻译
-
《Spring Security3》第四章第四部分翻译(Remember me后台存储和SSL)附前四章doc文件
-
《Spring Security3》第三章第四部分翻译(修改密码)
-
《Spring Security3》第四章第一部分翻译上(数据库管理信息)