说明:本来想多分几篇来写的,但似乎谈太具体的话,不适合放在这样一个标题下,所以这里先简单介绍一下,之后再视情况挑一些内容重点扯一扯
OpenID是一个开放的Authentication解决方案,关 于OpenID,我在06年的文章里已经谈过,不过那时谈的是最早版本的OpenID,也不知道是哪个版本,现在用的主要是OpenID Authentication 2.0及其周边的一些扩展功能。OpenID Auth 2.0基本原理与以前的版本没有本质的变化,只是在安全性和一些细节功能上有所增强。
基本的OpenID Authentication登录流程如下图:
1、首先用户在依赖方(即第三方网站)输入其OpenID URL进行登录(也可以直接使用提供方ID登录,这种方式则没有第2、3步);
2、(可选)依赖方从用户OpenID URL的页面中执行自动发现;
3、取得OpenID提供方的End Point URL;
4、(可选)依赖方与提供方建立关联;
5、取得关联的约定加密信息;
6、重定向用户浏览器到提供方;
7、用户登录到提供方并授权第三方的认证请求;
8、返回认证结果(是否通过用户身份验证);
9、重定向用户浏览器到依赖方,并提交认证结果;
10、依赖方向提供方验证用户提交的认证结果;
11、通过用户认证。
之 后,依赖方可以保存第9步的用户提交信息,在每次需要验证用户身份的时候,重复第10和11步向提供方验证用户身份。通常这项工作由session实现。 因为这两步需要多次进行,为了安全需要每次都必须进行签名验证,所以通常还是建议使用第4和5步的建立加密关联,以方便后续的验证操作。
过 程中的第2和3步就是OpenID分布式的关键,也是我在旧文中认为的OpenID的缺点(或者说是特性)之一。这一步可以让用户不受具体的提供方所限, 使认证成为分布式,但同时也使用用户的认证可靠性受这个OpenID URL对应的网站所限。所以现在很多OpenID认证应用都直接跳过这一步,使用固定(或有限可选的几个)提供方进行登录,使之从分布式身份验证成为第三 方集中式身份验证。其实我个人认为这样更好一些。而且这样还可以减少一对网络round trip,有助于改善登录速度。
在这一基础Authentication之上还有一些额外的约定,基 本的OpenID Authentication在验证通过以后,除了返回验证通过信息以外,还可以同时返回用户的Profile。当然,一般的Provider可以由用户 选择验证返回的Profile内容,比如myopenid.com可以选择返回一个完整Profile或是一个空白Profile(但仍然返回验证通过信 息)。那么关于个Profile就需要有一定的协议来约定。
在OpenID 2.0中主要是两个:简单注册扩展(Simple Registration Extension)和属性交换(Attribute Exchange)。
简单注册扩展约定了Profile的8个字段,实现起来较为简单。属性交换则更强大一些,可以双方约定任意数量和内容的字段,实现起来略复杂一些。
这也是Google提供给第三方的OpenID登录方式就是采用了属性交换约定。
属性交换的功能就是在依赖方提交验证请求 的 同时告诉Provider它需要哪些用户Profile信息字段(称为属性),然后用户在通过验证时,Provider将依赖方请求的属性告诉用户,由用 户决定是否允许(只能允许或拒绝,如果拒绝则验证不通过,不提供空白响应的选项)。
属性交换除了可以用于读取所选属性,还可以用于存储属性,当然这需要Provider方支持。
Google提供给第三方的OpenID登录流程如下图:
以上就是关于OpenID的基本介绍,具体的实现可以到官网下载各种语言实现的源码研究。
OAuth是一个开放的Authorization方案,可以说是基于OpenID发展起来的。因为OpenID不能提供Authorization功能:
比如某网站A提供了允许用户用TA的OpenID登录,但是如果某网站B需要用到网站A中该用户的数据,就无法通过OpenID来实现将网站A中的用户数据安全地授权给网站B——虽然可以让用户把自己的OpenID信息提供给网站B,让它以用户的身份登录网站A去取得,但这样的话如果网站B是一个恶意网站,它就可以以用户的身份登录任何其它支持该用户以OpenID访问的网站,带来严重的安全隐患。
于是人们需要一个开放的Authorization协议,于是OAuth诞生了。
目前OAuth有两个几乎完全不同的版本:OAuth 1.0和OAuth 2.0。
OAuth 1.0是一个被设计得非常安全的协议:除了Provider与Consumer之前的验证过程是相当安全的以外,它甚至要求对每一次的数据请求(API调用)都要进行请求内容的数字签名,以确保万无一失。
而OAuth 2.0则相当于对OAuth 1.0作了很大的简化:Provider与Consumer之间只是简单地交换一下密钥Key进行验证,之后Consumer只需要凭借验证后取得的一个Token就可以进行数据请求(API调用),没有太多的签名校验工作。
从技术上说,两个版本都可以实现Authorization功能,二者的差异在于:1.0更安全,但代价也更大(验证过程复杂,请求过程复杂);2.0更方便,但是安全性不如1.0(比如请求可能在传输过程中被修改)。
个人倾向于建议使用OAuth 2.0+HTTPS的方案,这样可以降低编程的复杂度,减少出错的概率,同时通过HTTPS保障安全性。
关于以上相关技术的实现,有空再来做吧。暂时计划包含:Google OpenID, Twitter OAuth 1.0, Foursquare OAuth 2.0