两个案例
第一个案例是几个月前,我收到一位朋友的邮件,邀请我加入一个叫ShoppyBag的网站。我去看了,没想到注册后就让我登录GMail帐号,并且GMail提示我该网站需要访问我的通讯录,于是我当即就中断了注册过程。
对于这类需要访问我的邮箱通讯录的网站我都是非常厌恶的,无数的垃圾邮件就是来自于它们。它们通过访问你的邮箱通讯录,然后向你的联系人们发邮件,然后迅速扩大了用户量可以向VC骗钱,而用户的隐私就这样被卖掉了,更不用说那些不请自来的垃圾邮件。
当然,虽然我中断了注册过程,但用户是已经注册成功了,只是访问网站时还会不时地提示我登录GMail。仔细看了它的提示内容后,发现有一行小字写着:
Your email address book contacts will be imported to your ShoppyBag Address Book.
ShoppyBag will not store your email login information or contact anyone without your permission.
我当然知道这种登录方式这个网站不会取得我的邮箱登录信息,它也可以假装未经授权不向我的联系人发邮件,但是我完全不想把我的通讯录COPY一份给它,因为只要那东西在它手上,我就不能保证它会拿来干什么。
之后还收到别的朋友也发来这个网站的邮件,而且在People You May Know里也看到很多熟人,不知道其中有多少人是中招的多少人是相信了这个网站的。
总之我是不信任这类网站,并且不会把通讯录授权给它们的。反正对这类SNS我也没什么兴趣。
这 个网站之所以可以取得用户的GMAIL通讯录,但是又不需要知道用户的密码,就在于它使用了GMAIL的一个授权(Authorization)功能的 API,当用户被定向到GMAIL登录页面时,用户选择允许以后,这个网站就可以通过GMAIL的通讯录API取得用户的通讯录了。
第二 个 案例也是几个月前在豆瓣小组,有人发布了一个他自己做的网站,因为要注册,我懒得去看,后来他说支持GOOGLE帐号登录,我就想去看看。结果是一登录GOOGLE 帐号就提示说这个网站要访问我的GMAIL通讯录。基于前所说的原因,我就把这个帖子给封了,那个楼主就发来豆邮兴师问罪。说是第三方用GOOGLE帐号 登录就是会这样的,但是很不幸我刚好最近也研究过这一块东西,知道并非如此。
所以我们需要先搞清楚一个问题,那就是认证和授权的区别。
Authentication和Authorization的区别
As we know,用户管理功能是大部分网站的基本功能,而这其中基本的基本就是用户身份验证,简单说就是登录——也就是“如何证明‘你’就是‘你’”。这就是所谓的Authentication。
用户管理的另一个基本部分(这个部分虽然基本,但不是必须的)则是权限管理——也就是“‘你’可以干什么”。这就是所谓的Authorization。
前 面两个例子中,第一个例子就是一种第三方Authorization,它试图让用户授权给它访问用户通讯录的权限。第二个例子则是错误地使用了 Authorization进行Authentication操作——当然,这里是以善意的角度来看这个网站,要是从恶意的角度上说,也可能它就是要用这 种方式来获取用户通讯录。
传统的应用中,Authentication和Authorization都是由应用程序自己进行处理的(即集 成 认证),相对来说问题少一些。只是对于应用开发者来说比较麻烦,每做一个应 用就需要把这一套全实现一次——Copy&Paste也是体力活啊。更麻烦的是对于用户来说,每到一个网站就要把注册流程走一遍,还要碰上用户名 冲突,担心密码安全之类的问题——很多网站对我来说最常用的功能就是:取回密码。囧
集成登录后的权限管理自然也是集成处理。
于是有了单点登录(SSO)——现在这已经是大网站的标配了,都是通过一个passport的统一登录点登录网站下的各个子功能。以及第三方登录——比如现在流行的用twitter或facebook帐号登录(国内对应的是用开心人人之类的帐号登录)。
单点登录后,具体应用取得登录信息,之后的权限管理也是应用程序自己处理,passport应用一般是不管的。
当然,最开放的还是分布式登录,比如OpenID。其实关于OpenID的话题,我早在06年就写过一篇《身份验证——谈谈OpenID 》。 现实的发展跟我的预期差不多——OpenID并没有能够得到广泛的应用,最近甚至有消息说,已经有一些网站取消了对OpenID的支持,因为用的人太少 了。目前OpenID协议用得多的话也只是用于第三方登录(相当于单点登录的一种)而不是分布式登录——比如用Google帐号登录其它网站。
这个时候就需要注意Authentication和Authorization的问题了——你一定不希望别人用你的GMAIL帐号给你的朋友发垃圾邮件甚至邮件吧?如果你是一个第三方应用开发者,你的用户当然也不希望。
以上三种方式的各自优缺点已经在前文里说过了,这里不再讨论。
Authentication 和Authorization两个概念相关性很高,很容易搞混,很多时候这也没什么问题,特别是集成认证的情况下,反正全都在统一控制之下。但是对于第三 方认证的情况下就需要考虑更多一些,最好还是把两种情况分清楚比较好。因此这里主要讨论第三方认证的情况。
第三方认证有很多方式,一般分 为 两类:认证方提供专有的API供认证,比如Microsoft Passport,早年Google也有Account API供Authorization使用(当时并不提供Authentication服务),提供了对日历和通讯录等的授权访问支持;另一类是采用开放方 案,这是目前的主流,最常用的就是OpenID和OAuth。
登录及认证流程
在整个登录认证过程中,可以分成几个参与 方:一个是认证提供方(Provider),另一个是认证使用方(Consumer),介于其中的就是被认证的用户(User)。除此之外,还有一个对 象,那就是服务(Service),即用户登录后所需要使用的功能——这才是用户登录的目的。之所以要单独提到这个Service,是因为它可能是由 Consumer提供,也可能有一部分是由Provider提供。如果Provider完全不提供Service,那Provider就是一个纯粹的 Authentication提供方,如果Provider同时还提供部分Service,比如GOOGLE提供的通讯录、日历等的服务给 Consumer,那么Provider同时还是一个Authorization提供方。
其实通常的分歧也就是出在后一种情况下。因为通常 对于用户的权限管理都是集成在提供Service的Consumer端,登录只是一个Authentication过程,单点登录(SSO)就是一个典型 的情况。只有在第三方登录的情况下才会发生需要认证方提供部分Service,这时才会有部分Authorization工作“外包”的情况。因此导致二 者的混淆与误用。
其实在整个过程中,User的目的只是为了使用Consumer提供的Service,验证身份及权限只是安全性的需要。
在 一个典型的第三方Authentication过程中,User向Consumer请求某个Service,Consumer就向Provider查询 User的身份,User通过密码等方式向Provider验证身份,并允许Provider将验证结果通告Consumer,Consumer在取得 Provider的验证通过结果后,向User提供相应的Service。
而一个典型的第三方Authorization过程中,User 向Consumer请求某个Service时,这个Service可能还需要第三方提供一些辅助的Service,比如通讯录,这时Consumer就要 向Provider请求访问User的这个Service,Provider则向User提示Consumer的这个请求,User通过密码登录 Provider并同意这个请求后,Provider把授权结果返回给Consumer(通常是通过返回一个Token),Consumer这时不但验证 了User的身份,同时还得到了它所需要的User的某些Service访问权限,之后它就可以以这个User的身份访问Provider的相关 Service了。
(上面本来想配两张图的,但是嫌麻烦,懒得画了-_-)
OpenID就是解决前一种场景,而OAuth则是解决后一种情况。
(待续)