讲讲LDAP,SAML,OpenID,OAuth2这些常见登录协议以及它们背后的故事
登陆是个啥?
登录这个操作,在我们日常使用各类网站,应用的时候,几乎是必须要做的事情。在计算机如此普及的今天,输入账号密码,点击登录按钮,我们每天都要重复干很多遍这样的事情。那么就是这个简单的登录按钮,我们去探究其背后的秘密。
看下一个最简单的登录过程,如图:
是不是觉得很复杂,看着有点晕?
登录按钮背后,其实包含了注册,登录与认证,授权,鉴权与访问,四个过程,一共四方参与其中来完成。
注册,是登录的前提。
用户需要向网站表明自己是谁,就是网站会分配给用户一个唯一的标识,通常就是用户名,用来确定用户在浏览网站时的身份。对网站来说,主要的目的就是为了将每个用户区分开来,进一步可以将每个用户的行为与数据区分开来,再进一步可以建立用户与用户的关系。
注册的结果,就是在数据库中会保存下用户的账号密码。为了安全起见,一般密码都会用MD5加密算法加密后保存,当然也不全是这样。国内之前最大程序员社区网站CSDN因为被******,导致账号密码泄露,发现密码是明文的,引发了不少吐槽,错了,是很多吐槽。
登录,目的是完成认证。
账号密码输入完毕,点击登录按钮,系统会将数据库中的账号密码跟输入内容进行比对,完全相同,则认为通过认证。认证,就是确定这个用户确实是他自己声称的那个用户。
授权,才是关键。
认证完成后,该用户凭什么能进入网站查看,这就需要授权。
重点来了!所谓授权,就是生成一个唯一的口令牌,常见的生成过程,就是将用户名,登录时间毫秒数,再根据个人喜好,加一些其它口味的参数,经过MD5加密之后,生成的一串16进制的字符串。这个字符串就是口令牌。
为了让用户不用每次来输入账号密码,一般这个授权都会有一段有效时间。用户只要凭借有效的授权就可以进入。
访问,之前需要鉴权。
用户获得授权后,对网站的其它功能页面发起访问。每次访问,都要将口令牌作为请求参数。口令牌失效,都会拒绝访问请求。口令牌,一般两种情况下会失效。一是过期了,二是用户主动退出登录。一般口令牌都有时效性,也就是在固定的时间过去后,再凭借这个口令牌访问系统,系统就会拒绝访问。过期时间越短,口令牌泄漏的可能性越小,安全性就越高。
整个过程就好比,用户去某大厦参观,先要在大厅前台那,用身份证登记(注册);你往里走就到总入口那,门口的保安队长要求你出示身份证核验后(登录与认证),会发给你参观证(授权),上面写着你是谁。保安队长会告诉你,参观证24小时有效,过了24小时,你需要重新来保安队长这里领取。用户拿着牌子访问大厦的每个房间,在每个房间门口都有一个保安,要求必须出示一下这个参观证才放用户进去(鉴权与访问)。
这里顺便插一句,现实生活中,身份证就好比用户名,用户肉身就好比密码。
上面就是最基本的登录过程,在普通网站中基本够用了。但在企业级产品里,还不够。因为一个企业里面可不止一个人,而是一群人。人一多,就自然有了组织结构。
下图是个常见的企业组织结构:
企业的组织结构,像一颗倒过来的树,在计算机术语里,这种数据结构就叫树(Tree)。那么在数据库中就需要通过数据来记录这种组织结构关系,我们定义一种叫组(Group)的概念,每个组有个唯一标识:组名。当一个用户属于某个组时,在这个用户的数据里面记录下这个组名即可。同样,一个组的数据也可以记录另外一个组名,表示这个组属于另外一个组。这里看下来有点绕,总之重点就是用数据能表达出这种结构关系就是了。
有了这个结构后,授权的过程就会变得更加复杂了。
企业中的每个人的权限是不同的。人数众多情况下,要给每个人设置对应权限无疑是繁琐的。正好,我们可以利用组织结构,不同的组拥有不同的权限,通过人在不同组里面,表现出不同的权限。
因此,授权的过程,就需要查看用户所在的所有组所对应的权限,来判断用户是否有访问当前功能页面的权利。
说到这里,才真正把登录有关的关键点都说了一遍,没看明白就再多看几次。读书百遍,其义自见。然后你以为要结束了吗?没有,登录的故事其实才刚刚开始...
登录的发展
随着集成电路,半导体等技术的发展,计算机硬件设备越来越普及,与此同时互联网也快速发展。在1980-1990年代,是飞速发展的时期。大量的企业开始使用计算机作为主流的办公工具。这时候,企业对软件的需求变得越来越大。
企业内部软件系统越来越多,简单的登录就带来了很多困扰:
- 各个系统都要求员工注册登录;
- 每个系统中都需要维护各自的组织结构;
- 等一个员工要离职的时候,还需要在每个系统中将此员工账号清除;
- 如果同一员工在不同系统的账号密码还不同,忘记账号密码就是再普遍不过的情况了;
于是计算机的先贤们,就想能不能将维护用户的账号密码,公司的组织结构不要如此繁琐?每个用户只需要一个账号密码,整个公司也只需要一个组织结构呢?
回顾下登录的流程,我们将账号密码,组织结构独立出来,做成单独的软件系统。那么账号密码,组织结构这些数据的保存,就都在这个独立的登录服务系统中,那么验证账号密码也可以在登录服务中就完成了。如图:
在1988年,由当时的国际电报电话咨询委员会(CCITT)推出的X.500计算机目录服务的标准系列协议中,包含由大名鼎鼎的互联网工程任务组(IETF)设计的LDAP协议(Lightweight Directory Access Protocol,轻型目录访问协议)。IETF就是设计TCP/IP协议族的那个标准组织。
协议,其实就是一个文档说明。就是一群大神发现,为了解决相同的问题,菜鸟们造出各种千奇百怪的轮子出来,看着实在难受。于是大神们聚在一起开了个会,甩出一篇文档说:照这个做就行。
LDAP协议是基于IP协议上的,意思就是基于互联网,得有网络才能工作。
LDAP协议主要规范了数据存储方式,以及验证账号密码的过程。LDAP要求账号密码,组织结构这些信息都保存在其系统中。LDAP也只负责对账号密码进行验证,其它比如该账号是否有权限访问当前应用,口令牌相关的验证,应用内部的权限等都不在LDAP的关心范围之类。
LDAP协议中,除了验证账号密码这个额外的功能外,看上去更像一个数据库,只负责数据存储和读取。它是特别的为了这种数据和数据之间互相关联的数据结构而设计的,这种东西,有个特殊的名字叫:目录服务(Directory service)。LDAP是目录服务中的一种。
目录服务的特点,就是读取快,写入慢。适合频繁读取而不经常写入的数据存储。目录服务的应用范围实际非常之广,有兴趣可以去了解一下。
LDAP有各种各样的实现,实现的意思就是一些公司或者个人,按照LDAP的协议,用代码真正的写出来了一个可运行的软件系统。
著名的LDAP实现有:
- 微软的AD(Microsoft Active Directory)
- 开源维护的OpenLDAP
对于一般软件应用,我们如果称某个应用兼容LDAP协议,也就是意味着,这个应用实现了对LDAP读写的API,这样只需要提供LDAP服务的IP地址等必要信息,该应用就能使用LDAP作为其账号密码验证的服务了。当然,具体不同应用对LDAP的使用方法多有不同,会存在不大不小的差异。
在LDAP的基础上,很好的解决了系统管理员要维护好多份公司结构和账号密码的问题,对于员工来说,也只需要记住一个账号密码就可以登录所有系统了。这在企业内部系统使用来看,似乎够用了。
也就在LDAP协议诞生后一年,1989年英国科学家 蒂姆·伯纳斯-李 发明了万维网。蒂姆·伯纳斯-李,就是图片上这位神仙。
Web领域经常提及的三个概念:
- 全球网络资源唯一认证系统,统一资源标志符(URI);
- 超文本标记语言(HTML);
- 超文本传输协议(HTTP)
都是他的个人发明,他还在1990年写编写了第一个网页浏览器。(拜拜Web之神,保佑网页不崩)
Web时代到来啦!
之前的互联网,网站方需要将自己的内容分享出来都要求用户安装特定的应用程序(没错,就跟现在手机APP差不多)。网站方要提供特定程序,对开发难度无疑是个挑战。而且在上世纪90年代初 ,拨号上网的滋滋声伴随的是几KB的网速,用户要下载安装各种五花八门的应用在自己那容量可怜的电脑里,对用户简直是个灾难。
Web的出现就彻底改变这一切。名叫WorldWideWeb的万维网在之后几乎成为互联网的代名词。网页浏览器成为用户连接世界的窗口。也正因为Web的发展,普通人买台电脑放在家里不再像是个摆设。
随着网站越来越多,网站类型越来越丰富,从开始只是完全开放式的只读网页,到逐渐拥有一些功能,需要区分用户行为,设定用户权限等等。
是的,他来了,他来了,我们的主角登录又出场了,网站也需要登录了。
Web系统开发起来简单,使得网站爆炸式增长,即使同一家公司也拥有多个网站服务。而用户这边,为了记住这么多网站的账号密码而疲惫不堪。相对于Web的易用性,登录各个网站都需要不停的输入账号密码显得格外繁琐。
能不要这么麻烦吗?
1998年,微软推出了Passport network服务,提供一个全球统一的用户身份服务。网络护照,顾名思义,就是用户注册Passport之后,将用户资料,如:名字,年龄,照片等等信息上传给Passport。其它网站接入Passport之后,用户在使用时就无需再次登录,用户只需要完成Passport的登录即可。这种一次登录就可以访问其它网站的理想,被称为单点登录(single sign-on,SSO)。
Passport失败了,大概是因为人们不信任微软。但是SSO的理念却引起了同行们的注意。SSO的想法就是将身份提供者(Identity provider,IDP),服务提供者(Service provider,SP)彻底分离,用户用IDP提供的身份就可以在Web世界畅通无阻。
这里面最让人头疼的其实是安全问题。如何保证用户的身份在逻辑上不能被冒充,才是最难的题目。数据加密,数字签名(Digital Signature)等各种密码学知识刚好解决了这个问题。这就是另外一大块的内容,暂且按下不表。
在2001年由OASIS组织安全服务技术委员会(Security Services Technical Committee)推出了SAML(安全主张标记语言,Security Assertion Markup Language),就是提出了对SSO实现的整体技术和安全规范。
SAML是以XML为基础,不用JSON的原因,大概是因为JSON一直在1999年才发明,2004年以后才流行起来逐渐取代了XML。在这之前,XML一直是作为网络通讯的标准格式。
在SAML协议中,实际上也包含了可以发送账号属性等登陆外的扩展部分。SAML协议实际内容很多,就不一一介绍,这里只围绕单点登录来说明。
SAML协议里,约定了参与SSO的三方:浏览器,身份提供者(IDP),服务提供者(SP),以及这三方相互的通讯次序,加密方法,传输数据格式。
在2005年推出了SAML 2.0,与老版本1.1互不兼容,但是解决的问题思路是一样的,2.0也是最新的协议,大概流程如下图:
跟LDAP的流程做一个对比,LDAP协议里只负责用户身份的认证,不包含授权过程。在SAML协议中,不仅包含身份认证,还包含是否允许用户访问当前网站内容的授权部分。
LDAP服务与应用之间是毫无条件的充分信任,LDAP几乎是作为应用的远程数据库一般的存在。而在SAML中,SP与IDP不仅需要在事前互相信任(互换签名公钥与IP地址),还要在认证过程中防止他人伪造而进行数据校验。因为SAML定义的SP与IDP是在互联网上相互独立的站点。
同时能注意到SAML协议非常依赖浏览器重定向功能,而LDAP协议都是应用与LDAP服务间的直接通讯。
浏览器重定向,其实就是指当前你访问的页面主动跳转到另外一个网站的网页上去,在跳转的过程中可以给这次访问网页的请求上附加上一些数据用来完成数据传输。
SAML的介绍差不多这些,这里我就不打算给你做一个什么生动形象的比喻来帮你理解这个事情了,相对有点抽象,反复看几遍,毕竟后面的更抽象。
实际上,除了SAML以外,同期还有不少其它协议或者方法提供SSO的解决方案,本质上都大同小异。任何SSO方案里,SP与IDP这两个概念都是最关键的两个角色。
在Web世界里,SSO理念被大家认可,也就得到了广泛的应用。比如现在我们在很多网站提供的微信登录,微博登录,都是SSO的一种实现。
互联网公司的某个产品用户有一点基数,就希望通过登录进一步扩大自己的影响,都纷纷实现自己的SSO方案。于是网上就会充斥着非常多的登录。国外就有Google登录,Facebook登录,Twitter登录等等,国内就有微信登录,微博登录,QQ登录,支付宝登录等等,也很多。你一个互联网公司没个登录都不好意思跟人打招呼。
像图片上这样,看着是不是也挺闹心的。
对用户来说,这些互联网产品我都得用啊,不是说好的用了SSO我就只需要一个账号密码了吗?咋还是这样呢?
再看看各大互联网公司,业务之间多少存在互相竞争,谁也不待见谁,统一?打通?门都没有。感觉SSO最初的美好愿望就要落空了。
写到这里,按照基本剧情,英雄就该出现了。
一个叫布莱德的程序员在1999年的时候,开发了一个类似博客一样的社区网站。运营的还不错,有了好几百万用户。你看,互联网公司,几百万用户,感觉可以开始做自己的SSO登录了。可这次布莱德不想做一个跟巨头们一样的东西,毕竟就算做出来估计也打不过。那要不要尝试去中心化的路子?
去中心化这个概念随着比特币流行而火爆了起来,其实去中心化这个概念很早就有了。中心化的意思就是用户在使用某项服务时,所有的访问请求都需要向同一个主体的服务器地址发送。比如每个微信用户的客户端,都是在跟腾讯公司的服务端交流,A发送给B一条消息,都是A先发送给腾讯服务端,再由腾讯服务端转发给B。A是不能通过其它公司或个人的服务端发送给B消息的。类似这样,所有用户都围着中间一个服务端,就管这种叫中心化的服务。
去中心化呢?就是并没有固定的一个服务商提供服务,任何人只要他愿意的话,都可以作为服务端来给用户服务,用户也可以自由的切换服务端。这种方式显然是不符合已经拥有大量用户的互联网公司的利益,但却迎合了用户和中小企业抱团取暖的需求。
于是布莱德在2005开始了一个叫OpenID的项目开发,这个项目在软件社区中得到了响应,越来越多的人参与进来,之后越来越多的人开始使用。OpenID的目的就是建立一个统一的SSO的方式,而不用在意IDP服务的提供方。用户完全可以自己启动一个IDP的服务,或者选择一个用户信任的IDP服务提供方,在这个IDP服务上完成注册。那么只要SP站点能使用OpenID的方式,用户就可以完成登录了。
大致流程如图:
因为提供OpenID的IDP服务并不确定在哪,所以在打开IDP的登陆页面之前,用户需要在SP提供的一个符合OpenID标准的表单上,输入下自己账号所在的IDP地址信息,以便让SP找到相应的IDP服务。
而且值得注意的是,OpenID只提供了认证,而并没有授权。也就是说OpenID的IDP只确认了确实有这个账号,而这个账号能不能访问该网站的内容,OpenID的IDP并不关心。
OpenID这种去中心化的特点,让账号这种资源或者权力不再被大企业独占而成为一种可能,在社区里面很快就广受欢迎。此后国外的一些主流网站也逐渐开始支持OpenID,国内互联网公司估计还没那么快想得开。
在2006年,在Twitter工作的库克正在负责给Twitter支持OpenID的工作。与此同时,社交书签网站Ma.gnolia需要一个解决方案允许使用OpenID的成员授权Dashboard访问他们的服务。
来,我们来理解一下这个需求。
用户用同一个账号在甲乙两个站点都有登录,甲想要调取乙的数据,通常要访问乙,都需要乙的口令牌,才能访问,那如果将乙的口令牌直接告诉甲,那就相当于甲在乙那边有跟用户相等的权力,很难保证甲不拿这些去干些越权的事情。那么,在不将乙的凭证交给甲的前提下,我们是不是可以额外给甲一个临时授权,这个临时授权,规定好使用时效和使用范围就可以了。乙收到这个临时授权,一定要核验一下到底是哪个用户,这样才能准确的给出资源。
基本流程如图:
于是,库克跟几个人凑一起鼓捣了近一年,在2007年推出OAuth协议草案,翻译过来叫“开放授权”,算是给OpenID的一个补充。
你看时间已经来到了2007年,2007发生了一件大事情。
乔布斯发布了第一代苹果手机。
紧接着2008年HTC推出了第一部Android手机,彻底拉开了移动互联网时代的序幕。Web似乎一时间跟失宠了一样,开发者们大量的投入到了手机APP的开发中去。
之前的SAML协议十分依赖浏览器的重定向功能,在移动手机时代就显得过时了,不好用了。OAuth1.0也是在Web时代诞生的,而且因为第一个版本太复杂,虽然有一些人发现其价值,但一直动静不大。在2009年还发现协议里有个安全漏洞,虽然后来打了个补丁,但是总归影响不太好。
于是OAuth团队就干脆放弃了第一个版本。在2011年5月发布了OAuth2.0草案。OAuth2关注客户端开发者的简易性,同时为Web应用、桌面应用、手机和智能设备提供专门的认证流程。
现在大部分常见的登录后面都借鉴了OAuth2的授权流程,比如在用微信登录了一个网站后,总是还要弹出一个页面,问你允不允许该网站使用你的微信头像和名字,这就是授权的过程。只是在微信这个例子里面,IDP和第三方服务都是微信一方。
另外从流程图我们可以了解到,IDP与SP都是需要互相知道对方的位置,并且在授权流程开始之前,都需要互换公钥来保证信息安全不被伪造,这就是OAuth2的注册过程。
这上面的例子主要是Web下的流程,手机和桌面应用的流程会有所区别,这个感兴趣可以自己查阅相关资料。
在OAuth2推出之后,OpenID的团队在2014年将OAuth2的理念与OpenID相结合,并作出一些简化,发布了OpenID Connect协议。简单理解OpenID Connect就是认证跟OpenID一样,授权跟OAuth2一样。其实内部技术细节有不少差别,但这里就不细说了。
就这样,伴随着软件和互联网的发展,登录相关技术也随着大神和英雄们的出现悉数登场。从LDAP,SAML,OpenID,OAuth2这一路的发展,也不过短短30年光景,不得不感慨计算机技术日新月异的速度。
企业信息化水平也随着计算机技术的发展不断进步,企业依赖软件的程度也越来越高。企业使用的这些软件,因为不同的时间,不同的需求,而采用了各种不同的登录技术,这使得企业内部想做到真正意义上的SSO依然面临诸多问题。
那我们能不能再进一步去解决这些问题,至少在企业内部能真正意义上做到SSO呢?用统一的账号登录,既能登录这些有年头的软件系统,能轻松接入现有流行的软件系统,还能给未来待开发的软件系统予以一定规范和帮助?
龙归科技在2019年开发并推出一款代号ArkID开源项目:龙归一账通,就是针对企业目前在实现SSO方面的问题而提出的解决方案。
ArkID兼容本文介绍的和没介绍的现有流行的各类用户登录协议,包括LDAP,SAML2,OpenID,OAuth2等等,同时ArkID还对外提供完整的API,方便接入各种新老系统,完成真正的单点登录。
ArkID支持账号同步,各类第三方账号登录(如微信,钉钉等),支持企业组织结构,支持应用授权。
ArkID完全可以跟LDAP一样,作为远程账号与组织结构数据库,甚至支持了对应用内权限的相关数据存储。
ArkID提供的登录页面,允许自定义名字和颜色。同时将基于Vue的前端页面和管理后台开源,可以随心所欲的定制。
ArkID同样支持了完整的登录日志,支持了用户行为审计。
一账通产品页:https://www.longguikeji.com/product/arkid
源代码:https://github.com/longguikeji/arkid-core