这几天做了一个OPENID的项目,从开始的不知道所云,到后面的深入了解,也经历了一些过程,在此记录一下,希望对刚接触的朋友有所帮助。
1、首先对OPENID的了解,参看了网上的一篇文章:
OpenID是一种开放、离散式的用于用户数字标识的开源框架。
请让我们思考自己所拥有的在线帐号种类:博客、wiki、to-do list、个人相册。在网络应用日益充斥的今天,这些个人在线帐号可谓不胜枚举,而对帐号的需要也同样无处不在,乃至当我们想在好友博客上进行评论时都需要注册成为该博客系统的用户。于是作为终端用户,我们不得不在每个网站上设置帐号,并管理众多的帐号。而采用OpenID技术的话,你就无须再管理这些相互独立的帐号,而是通过认证服务器管理自己唯一的身份标识。
OpenID常见的应用场景:某用户试图登录一个外部网站。与提交用户名和密码的方式不同,他只提交了属于自己的一个URL,例如:http://johnsmith.example.com/
这个URL即指向了用户的OpenID认证服务器,同时又是用户的身份标识。因此外部网站使用此URL便可以找到用户的认证服务器,并询问认证服务器:“该用户声称他拥有此URL。而这个URL说明了你负责认证工作,那么请告诉我,该用户能否访问我的站点?”。认证服务器将提示用户登入认证系统,并询问用户是否允许和外部网站进行认证。如果用户同意的话,那么认证服务器将通知外部网站——用户已经通过认证。在上面,我们通过拟人化的表达方式来形象生动地诠释整个认证请求/回应过程。
用户可以使用同一个URL用作在任何支持OpenID认证的外部网站中使用的标识。这正是OpenID与其它传统认证方式的最大不同。通过使用URL,可以使外部站点非常容易地获取到负责认证工作的服务器位置。而只有认证服务器才需要输入密码来验证用户身份。其它希望验证用户身份的站点都将询问用户所注册的认证服务器。如果你正在使用支持OpenID的门户站点(比如AOL),那么你就可以使用现成的AOL即时消息登录帐号来登录AOL站点,而无需另外注册。因此,我们可以猜想Google和Yahoo也许已经开始着手建造他们的OpenID服务。
你一定想知道OpenID是如何实现分散化服务的?由于用户具有选择OpenID服务提供者的权利,因此你会在最初选择AOL作为OpenID提供者,而过一段时间后,可能觉得希望更换到另外一个OpenID提供者,此时你所需要做的就是修改以下的HTML标签:
<link rel="openid.server" href="http://openid.example.com/">
保存这些link元数据的最常见位置就是个人站点(比如博客)的根页面。
2 对OPENID的协议的理解是很重要的,再转载另一朋友的文章:
OpenID协议非常易于扩展,下面的图表展示了OpenID2.0草案的基本工作流程。它展示了在终端用户、Relying Party站点(一个示例站点)和OpenID服务提供者之间的交互过程(最常见的认证流程)。
用户登入外部站点(RP)的过程主要分为以下七个步骤:
1 请求用户ID
第一步当然是要求用户提供 OpenID 了。不过这个 OpenID 也是有说法的, OpenID 可以以 URL 的形式存在,就是我们熟悉的 http 或者 https ,也可以是 XRI 的形式,不过现在为止我还没有发现 XRI 形式的 OpenID ,先放到一边不管,知道就行了。有时间看看 XRI 的语法规范 ,内容好像不是很多。
2 整理 OpenID
其实呢,用户在输入 OpenID ,点击登录之后, RP 就开始忙活了,首先就是要检查用户的 OpenID 是否符合规范,如果不符合规范,就要对 OpenID 进行修正或者补全。比如我的 OpenID 是 http://tihualong.myopenid.com 如果我输入了 tihualong.myopenid.com ,你也得认出来 ( 不然这么弱的话,谁喜欢用啊,偷懒都不能偷懒 ) 。而且更可恶的是需要考虑到 OpenID 有可能是 XRI 的形式,更增加了标准化的复杂性。该死的兼容性 ( 使用 XRI 的用户也是这么想的吧,呵呵 ) 。列一下整理的规则
1 以 xri:// xri://$ip 或者 xri://$dns 开头的,统统砍头,去掉这些标识
2 如果余下的字符串第一个字符是 xri 的全局标识符,那么它已经是规范化的 OpenID 了,否则视为 HTTP URL 进行处理,没有 http 或者 https 头的,加上 http 。
下面是一些例子:
用户输入的OpenID |
规范化的OpenID |
OpenID类型 |
=example1 |
=example1 |
XRI |
xri://$dns*example3.com |
=example2 |
XRI |
xri://$ip*1.2.3.4 |
URL |
|
URL |
||
URL |
||
example6.com |
URL |
下图是参考文章上 OpenID 的整理流程
看起来好像也不是很复杂。不管,反正不是自己写,都有人封装好了。
3 发现阶段, RP 查询与 OP 进行通讯的方式
话说这个阶段是非常重要的, RP 使用整理过的 OpenID 查找发出请求必需的参数, RP 会瞒着用户偷偷的跟 OP 接头, RP 把自己假装成一个用户,向 OP 询问要发出一个合法请求需要提供哪些参数, OP 会返回给 RP 一个 XML 文档,告诉 RP ,我需要哪些哪些参数,这个 OpenID 的服务地址是什么什么,你要将用户重定向到哪里哪里进行登录验证等等。当然这些过程都是在用户不知道的情况下进行的。
而且,比较重要的一点是:这个阶段使用的协议以及返回的结果文档都取决于整理阶段查到的 OpenID 的标识类型
OpenID类型 |
协议 |
结果文档 |
XRI |
XRI |
XRDS |
URL |
Yadis |
XRDS |
URL |
HTML Discovery |
HTML |
4 RP 与 OP 建立关联
创建 RP 与 OP 关联之后,可以在两者之间使用加密的方式验证后续的协议消息并降低通信数 ( 不知道这样理解对不对 ) 简单来说,就是使用了一种 Diffie-Hellman 密钥交换算法生成的共享密钥对传递的消息进行数字签名。
这种机制能保证 RP 与 OP 可以进行安全的进行通信,这种安全性可以通过在传输层使用 SSL 协议或者使用 HMAC SHA1 或者 HMAC SHA256 实现。 RP 请求成功后会得到一个通讯句柄, RP 和 OP 将会在后续的活动中将它作为对消息进行加密的密钥使用。
这一步骤是可选的,因为 OpenID 协议允许不通过建立关联直接请求认证,接着请求对认证信息进行验证。这样 RP 可以是无状态的,不需要保存通讯句柄 ( 在协议中这种方法号称 dumb 模式:沉默模式 ) ,这种方式被推荐用于执行与 OP 的通信,但是如果不能用这种方式,就必须建立关联。
( 有关 openid 的加密验证模式可以参考 http://tenglong.blog.51cto.com/180708/29866)
注: OpenID 认证同时支持 “ 智能模式 ” 和 “ 沉默模式 ” 来容纳不同的 RP 。 一个智能的 RP 用保存状态信息的方式以便在开始阶段完成少许的工作。 一个 “ 沉默模式 ” 的 RP 则是完全的无状态的,但是需要一个额外的 HTTP 请求。