最近花了较多时间学习单点登陆以及相关的安全技术,做一个简单的总结,发表我的一些看法。抛砖引玉,希望各位朋友参与讨论。
单点登陆,鸟语原文为Single Sign-On,缩写为SSO。别以为单点登陆是很时髦高深的技术,相反单点登陆是很古老的技术,例如1980年kerberos v4发布,一直发展至今,被Windows、Mac OS X、Linux等流行的操作系统所采用,是为应用最广泛的单点登陆技术。
kerberos适用于局域网,十分成熟。互联网发展之后,多个网站需要统一认证,业界需要适合互联网的单点登陆技术,也就是WEB SSO。2002年,微软提出了passport服务,由微软统一提供帐号和认证服务,理所当然,大家都不愿意受制于微软,但是很认同微软提出WEB SSO理念,于是产生了Liberty Alliance,另外指定一套标准,这套标准发展起来就是SAML,目前SAML的版本是SAML V2,属于OASIS的标准。
--------------
SAML
SAML,鸟语全名为Security Assertion Markup Language,弥漫着学院派的腐尸味道,缩写十分怪异,令人望而生畏。计算机行业,向来崇尚时髦,SAML这一名称使得其较少受到大众程序员的关注。
SAML的标准制定者,来自SUN、BEA、IBM、RSA、AOL、Boeing等大公司,制定技术规范相当专业有水准,系统分层合理,抽象了几个概念把整个系统描述得很清楚,使用流行技术XML Schema来描述协议,使用到了XML-Sign和XML Encrypt等较为前缘XML安全技术。
SAML的基本部分包括Protocol、Bingding、Profile、Metadata、AuthenticationContext。其中Protocol是交互消息的格式,例如AuthnRuequest/Response(认证请求/响应)的消息对。Bingding是指协议所采用的传输方式,例如使用HTTP Redirect或HTTP POST或SOAP的方式传输Protocol中所定义的消息。Profile是系统角色间交互消息的各种场景,例如Web Single Sign-ON是一种Profile、Single Sign-Out也是一种Profile、身份联邦也是一种Profile。各个参与方所提供的服务的描述信息为metadata。系统的认证方法通常是千差万别的,AuthenticationContext是SAML中定义的认证扩展点,可以是最普通的User Password认证,也可以是kerberos认证,也可以是电信常用的RADIUS,或者是动态密码卡。
SAML在Java企业应用中,得到广泛支持,IBM、BEA、ORACLE、SUN的Java应用服务器都提供了SAML的支持,曾经有人说,SAML就是如同JDBC一样,将会是使系统集成的准入证。SAML有很多开源实现,包括SUN公司的Open SSO,不幸的是,这些开源实现都不够好,或者相当糟糕,如果我们需要支持SAML协议,可能需要在开源的版本上裁剪或者另行开发。
SAML考虑了Web SSO,也考虑了传统的SSO集成,包括Kerberos和LDAP的集成,其中Attributed扩展机制以及相关规范,使得SAML拥有良好的扩展性,很好集成传统协议和支持新协议。
SAML是一个定义良好的规范,概念清晰,分层合理,扩展性良好,一切都很棒,但是有一点不好,就是曲高和寡!
-------------
OpenID
有一些互联网公司,拥有众多很多帐号,很牛B,例如GOOGLE、YAHOO、Facebook,希望别人的系统使用它们的帐号登陆。他们希望一种足够简单的WEB SSO规范,于是选择一种草根网络协议OpenID。OpenID,名字取得好,顾名思义,一看就知道它是干嘛的。国内也有它的Fans,例如豆瓣网。openID的确足够简单,但是协议本身是不完善,可能需要一些补充协议才能够满足业务需求。例如GOOGLE采用OpenID + OAuth。目前支持OpenID有Yahoo、Google、Windows Live,还有号称要支持OpenID的Facebook。目前Yahoo和Google宣称对OpenID的支持,但是其实是有限制的,Yahoo的OpenID只有少数合作伙伴才能获得其属性,Google也只有在其Google Apps中才能获得账号的Attribute。用户账号毕竟是一个互联网公司的最宝贵资源,希望他们完全分享账号是不可能的。
Open ID和SAML两种规范,都将会减少系统间交互的成本,我们提供Open API时,应该支持其中一种或者或两种规范。
--------------
OAuth
oAuth涉及到3大块的交互和通信。1. 用户,2. 拥有用户资料/资源的服务器A,3. 求资源的服务器B,。
oAuth的典型应用场景(senario)
以前,用户在 拥有资源 的的网站A有一大堆东西;现在用户发现了一个新的网站B,比较好玩,但是这个新的网站B想调用 拥有资源的网站A的数据。
用户在 求资源的网站B 上,点击一个URL,跳转到 拥有 资源的网站A。
拥有资源的网站A提示:你需要把资源分享给B网站吗?Yes/No。
用户点击 Yes,拥有资源的网站A 给 求资源的网站B 临时/永久 开一个通道,然后 求资源的网站 就可以来 拥有资源的网站 抓取所需的信息了。
(参考资料:http://initiative.yo2.cn/archives/633801)
(摘抄)
--------------
内部系统间集成使用LDAP、Kerberos,外部系统集成使用SAML或者OpenID + OAuth,这是一种建议的模式。
------------
PAM
人们寻找一种方案:一方面,将鉴别功能从应用中独立出来,单独进行模块化设计,实现和维护;另一方面,为这些鉴别模块建立标准 API,以便各应用程序能方便的使用它们提供的各种功能;同时,鉴别机制对其上层用户(包括应用程序和最终用户)是透明的。直到 1995 年,SUN 的研究人员提出了一种满足以上需求的方案--插件式鉴别模块(PAM)机制并首次在其操作系统 Solaris 2.3 上部分实现。插件式鉴别模块(PAM)机制采用模块化设计和插件功能,使得我们可以轻易地在应用程序中插入新的鉴别模块或替换原先的组件,而不必对应用程序做任何修改,从而使软件的定制、维持和升级更加轻松--因为鉴别机制与应用程序之间相对独立。应用程序可以通过 PAM API 方便的使用 PAM 提供的各种鉴别功能,而不必了解太多的底层细节。此外,PAM的易用性也较强,主要表现在它对上层屏蔽了鉴别的具体细节,所以用户不必被迫学习各种各样的鉴别方式,也不必记住多个口令;又由于它实现了多鉴别机制的集成问题,所以单个程序可以轻易集成多种鉴别机制如 Kerberos 鉴别机制和 Diffie - Hellman 鉴别机制等,但用户仍可以用同一个口令登录而感觉不到采取了各种不同鉴别方法。PAM 后来被标准化为 X/Open UNIX® 标准化流程(在 X/Open 单点登录服务(XSSO)架构中)的一部分。(摘抄)
如果我们设计一个认证系统,PAM是应该参考借鉴的。
-------------
JAAS
Java Authentication Authorization Service(JAAS,Java验证和授权API)提供了灵活和可伸缩的机制来保证客户端或服务器端的Java程序。Java早期的安全框架强调的是通过验证代码的来源和作者,保护用户避免受到下载下来的代码的攻击。JAAS强调的是通过验证谁在运行代码以及他/她的权限来保护系统面受用户的攻击。它让你能够将一些标准的安全机制,例如Solaris NIS(网络信息服务)、Windows NT、LDAP(轻量目录存取协议),Kerberos等通过一种通用的,可配置的方式集成到系统中。在客户端使用JAAS很简单。在服务器端使用JAAS时情况要复杂一些。(摘抄)
-------------
Spring Security,Spring框架大名鼎鼎,Spring Security属于SpringFramework旗下的一个子项目,源自acegi 1.x发展起来。很多人项目应用了spring security,但我个人看来,spring security绝对不算是一个设计良好的安全框架。其设计感觉就是一个小项目的安全认证实践罢了。
-------------
CAS
应用最广的开源单点登陆实现了,其实现模仿Kerberos的一些概念,例如KDC、TGS等等,都是来自于Kerberos。CAS对SAML和OpenID协议支持得不够好。个人感觉类似Kerberos的机制在互联网中可能过于复杂了。我感觉单纯的ticket机制,过于局限于基于加密解密的安全了,感觉上SAML的Assertion概念更好,Assertion可以包括认证、授权以及属性信息。
-------------