无论是Web端还是移动端,现在第三方应用账户登录已经成为了标配,任意打开个网站都可以看到,QQ/微信账号登录的字样。使用第三方账户的登录的过程,既要限制用户身份只让有效注册用户才能登录,还要根据注册用户的不同身份来控制能浏览的内容,这就需要认证和授权
相关文章链接:
1. 何为认证,何为授权
认证(authenticate)和授权(authorize)是两个容易被弄混的概念,尤其是只看英文。
认证意味着证实某个用户是他所声明的那个人;授权意味决定一个身份确定的用户能够访问那些资源。
由此可见,应用需要先认证用户身份,然后依据用户身份再授权,二者需要联合使用。
对于QQ或者微信这样的应用,用户在登录后会得到该账户的身份凭证。如果其他第三方应用信任并接受QQ或者微信的身份凭证,就可以直接使用该凭证通过第三方的认证而登录。登陆之后用户能有权限去做什么,这就是第三方应用根据自己政策而进行的授权。我们常遇到有网站在第一次使用QQ或微信账户登录之后需要绑定已用账户,就是因为虽然网站能够通过QQ账户的身份认证,但是对于这样的账户没有对应的授权。
同理,对于一个面向公司内部的服务环境,该公司可能有邮箱系统、网上办公系统、财务系统等等。如果这些系统都是独立的,那么公司的员工就需要每一个系统都分配一个账户,每个系统都需要单独登录。这样显然是低效而麻烦的,更好的解决方案应该是用户在内网中只需要登录一次,所有的子应用系统都能认证其身份,而免去重复登录,这样的方案就被称为单点登录(single sign-on, SSO)。
这样做的最明显的好处就是提高用户体验,用户只需要维护一对用户名和口令可以在公司内部畅通无阻。同时,因为是单点登录,所有的用户身份的都被统一认证,也就是说用户的身份凭据(比如口令)只被保存在一处,其他子系统并不直接获得用户的口令等敏感信息,而是接收来自可信来源的身份证明。
单点登录和统一认证中主要的三个协议是OpenID, OAuth, 金和 SAML,被称为单点登录的三驾马车。这些协议已经有了各种语言版本的实现,本人也在其他文字做了详尽的介绍,这里专门对比下三种协议的异同。
2. OpenID
OpenID是一种认证标准,互联网上有很多账户都是支持OpenID比如谷歌、雅虎、PayPal等等。
用户要使用OpenID就必须先在OpenID身份服务器(Identity Provider, IDP)获得OpenID 账号(比如Google账户)。用户可以使用OpenID账户来登录任何一个接受OpenID认证的服务应用(the relying party,RP,依赖方)。OpenID协议标准就是提供一个框架用来IDP和RP之间通信。
![](https://upload-images.jianshu.io/upload_images/3297585-a0dbfdd8c5f79c51.png?imageMogr2/auto-orient/strip|imageView2/2/w/471/format/webp)
本质而言,用户的OpenID是一个为用户个人所拥有的特殊URL(比如 alice2016.openid.com),所以有些网站甚至会提供选项让用户自己去填写OpenID。
![](https://upload-images.jianshu.io/upload_images/3297585-7f674a2467902ad0.png?imageMogr2/auto-orient/strip|imageView2/2/w/811/format/webp)
FaceBook曾经也是使用过OpenID的,后来转而开发FaceBook Connect.
OpenID的最新版本是OpenID Connect。具体协议信息请见这里 OpenID Connect 协议入门指南
3. OAuth2
准确来讲,OAuth2是一个授权的标准协议。也许会令人困惑,OAuth2是OpenID-Connect的基础,但是OpenID-Connect是认证协议(在OpenID-Connect中,ID-Token也被当做是一种资源)。
让我们回到OAuth2,OAuth2提供了一种代理访问机制,也就是说一个应用(可以被称为客户端)可以代替用户到资源服务器上获得属于用户的资源或是进行符合用户权限的操作 ,而用户不用将自己的用户名和口令等身份凭据分享给客户端。OAuth2是通过IDP给第三方应用颁发令牌(Token)来实现以上功能的,第三方应用通过使用令牌向资源服务换取对应的资源。
在Twitter的OAuth指导手册中说OAuth2是一种认证协议,实际上,这是基于授权的“伪认证”。
OAuth协议的认证过程可以类比为如下流程:Alice要外出一段时间,让自己的朋友Bob代为照顾她的房子,所以Alice把自己房子的钥匙交给了Bob,而Bob也就可以任意的进入房子。这里的钥匙就是一种授权的体现——Alice授权Bob进入房子。在这里例子中,房子的所有者Alice就是用户,Bob是客户端,而门锁就是IDP,房子是资源服务器。
如果假设房子钥匙的拥有者就是房子的所有者,那么这个授权的过程也是一种伪认证,之所以加一个伪字,是因为
这个假设并不是总是成立的,比如Bob虽然有钥匙,但是并不是房子的所有者Alice。
更多OAuth的内容,请参见我之前的文章。OAuth2.0 协议入门指南
4. SAML
SAML协议是三者中时间最长的协议,最初版本制定于2001年,并于2005年修改。作为一种安全性断言标记语言,SAML协议既可以用于认证也用于授权。
所谓的安全性断言,就是关于认证、授权以及用户属性(比如用用户的有效或者住址等信息)的声明集合,在SAML中,这些断言以XML的格式传输。
当要验证一个用户身份时,服务提供商(Service Provider, SP,即RP,应有依赖方)会向IDP发出SAML认证请求,该请求中会以XML格式说明认证方式的设置,比如希望IDP以何种方式验证用户;IDP在认证通过用户身份之后,会返回SAML请求响应,同样以XML格式返回断言表明用户身份和相关属性,此外SAML安全性断言信息必须要使用数字签名以保证其完整性和不可抵赖性(没有强制要求对SAML断言加密);SP接收到SAML断言之后,验证其消息来源是否费受信任的IDP,验证通过之后解析XML获得认证信息。
除了断言,SAML还定义了如下概念:
- 协议(protocols):如何请求和响应断言信息;
- 绑定(binding):SP和IDP之间如何通信和传递数据;
- 配置描述(profiles):用来设置断言、协议和绑定的中所需要使用的变量。
更为详细的内容请见:
5. 协议的对比
以下是三种协议的相关对比和总结,便于读者根据自己实际情形来选择下一步要继续去了解哪一种协议。
对比点 | OAuth2 | OpenID | SMAL |
---|---|---|---|
票据格式 | JSON or SAML2 | JSON | XML |
支持授权 | Yes | No | Yes |
支持认证 | “伪认证” | Yes | Yes |
创建年份 | 2005 | 2006 | 2001 |
最新版本 | OAuth2 | OpenID Connect | SAML 2.0 |
传输方式 | HTTP | HTTP GET and HTTP POST | HTTP重定向,SAML SOAP绑定,HTTP POST绑定等 |
安全弱点 | 不能抵抗网络钓鱼,OAuth没有使用数据签名和加密等措施,数据安全完全依赖TLS | 不能抵抗网络钓鱼,一个钓鱼的IDP如果恶意记录下来用户的OpenID,将会造成很严重的隐私安全问题 | XML签名存在漏洞,可能被伪造 |
使用场景 | API 授权 | 商用应用的单点登录 | 企业级单点登录,但是对于移动端支持不是很好 |
6. 深入了解
如果想进一步以上协议的具体,欢迎阅读我的其他文章: