通行证系统

引言

背景

随着信息技术和网络技术的迅猛发展,一个企业的应用系统会越来越多,这样会带来很多的开销;其一是管理上的开销,需要维护的系统越来越多,很多系统的数据时相互冗余和重复的,数据的不一致性会给管理工作带来很大的压力,业务与业务之间的相关性也越来越大,为了降低管理的消耗,很多企业都在进行企业应用集成(EAI)。企业应用集成可以在很多层面上进行:例如在数据存储层方面的“数据大集中”,在传输层上的“通用数据交换平台”,在应用层面的“业务流程整合”,用户界面层上的“通用企业门户”。事实上,还有一个层面的集成变得越来越重要,那就是“身份认证”的整合,也就是单点登录。这就是本方案要解决的问题。因为这些系统相对独立,用户在使用每一个系统时都要按照相应的系统身份进行登录,为此用户必须记住每一个系统的用户名和密码,这样会给用户带来不少麻烦。针对于这种情况,产生了统一用户管理及认证单点登录等概念,同时不断被运用到企业应用系统中。

定义

统一用户管理

一般来说,每个应用系统都拥有独立的用户信息管理功能,用户信息的格式、命名和存储方式也不同。当用户需要使用多个系统时就会产生用户信息同步的问题,从而增加系统的复杂性和管理成本。
解决用户同步问题的根本办法就是建立一个统一用户管理系统(Unified User Management System, UUMS)。UUMS统一存储所有应用系统的用户信息,应用系统对用户的操作也通过UUMS来完成,而授权等操作则由各应用系统自己完成,即统一存储,分布授权。

UUMS应该具有以下功能:

  • 用户信息规范命名,统一存储,用户ID全局唯一。用户ID就像身份证,区分标识不同的个体。
  • UUMS向应用系统提供用户属性列表,如姓名,电话等,各应用系统可以选择自己需要使用的部分或全部属性。
  • 应用系统对用户信息的增删改查等操作由UUMS来完成。
  • 应用系统保留用户管理的功能,如授权,分组等。
  • UUMS应具有完善的日志功能,详细记录各应用系统对UUMS的各项操作。

统一用户认证

统一用户认证以UUMS为基础,为所有应用系统提供统一的认证方式和认证策略,以识别用户身份的合法性。

统一用户认证应该支持以下几种认证方式:

  • 匿名认证方式:用户不需要任何认证,可以匿名的方式登录系统。
  • 用户名/密码认证:最基本的认证方式。
  • PKI/CA数字证书认证:通过数字证书的方式验证用户身份。
  • 手机短信验证:通过用户输入发送到手机的验证码验证用户身份。

认证策略:

  • IP地址认证:用户只能从指定的IP地址或地址段访问系统。
  • 时间段认证:用户只能在指定的某个时间段访问系统。
  • 访问次数认证:累计用户的访问次数,使用户的访问次数在一定的数值范围之内。

以上认证方式应该以模块化的方式设计,系统能灵活的装载和卸载,并且还能方便的按新需求开发新认证模块。
认证策略指认证方式通过与、或、非等逻辑关系组合后的认证方式。

单点登录

单点登录(Single Sign On,SSO)是一种方便用户访问多个系统的技术。简单的说就是在一个多系统共存的环境中,用户在一处登录后,在一定时间内,不用再在其他系统中登录了;也就是说用户在一个系统登录后能得到其他系统的信任。在现实生活中的实例就是旅游景点的套票,只要在大门口买了套票,那么在每一个独立的景点,只要出示票据(Ticket),各景点验证这个票据的有效性,不需要在每个景点都买票了。
单点登录的实质就是一个信任凭证在多个应用系统中的传递和共享。当用户登录系统时,客户端根据用户的用户名和密码等为用户创建一个信任凭证,包括用于验证用户的安全信息(Ticket之类的),系统用这个信任凭证来判断该用户是否有能访问系统资源。这样一来,实现单点登录说到底就是要解决如何产生和存储那个信任凭证,再就是其他系统如何验证这个信任凭证的有效性,因此要点也就以下两个:

  • 存储信任凭证
  • 验证信任凭证

只要解决了以上的问题,达到了开头讲得效果就可以说是SSO。

现假设有以下资源:

  • 身份验证服务器 PS
  • 应用站点 A1
  • 应用站点 A2

最简单的实现方法是用Cookie,交互步骤如下:

  1. 用户访问A1,A1取用户的域(如:iwgame.com)下的Cookie,不能找到Cookie,则重定向到PS,请求身份验证;
  2. PS验证成功后,为用户设置Cookie,重定向到A1;
  3. 用户访问A2,可以获取到域(iwgame.com)下的Cookie,验证用户已登录,直接访问A2。

这种方案是将信任存储在客户端的Cookie中,但是这样的话有两个问题,即:Cookie不安全和不能跨域。对于第一个问题可以通过加密Cookie来解决,第二问题就是硬伤了。

这样,就有了第二种方案,把信任关系存储在服务端,交互步骤如下:

  1. 用户访问A1,A1查看Session中是否有登录信息,如果没有则重定向到PS,请求身份验证;
  2. PS 验证成功后,生成Ticket票据,将Ticket票据连同A1的SessionId一并保存在PS(内存或持久化),并在用户浏览器设置Cookie,确保已登录。之后PS重定向到A1,并传递Ticket号给App1;
  3. A1收到PS回传的Ticket号,根据这个Ticket号在后台与PS建立安全连接并验证Ticket的有效性,然后保存PS传回的用户信息。登录成功;
  4. 用户访问A2,A2发现Session中没有登录信息,转向PS要求验证;
  5. PS获取用户Cookie,发现用户已经成功登录过。于是把PS根据Cookie中的信息生成Ticket参数给A2,接下来的A2的验证过程和步骤3一样。

同样,这种方案也面临几个问题需要解决。一是如何高效的存储大量临时性的信任数据,二是如何防止信息传递过程被篡改。
对于第一个问题,一般可以采用类似与Redis缓存的方案,既能提供可扩展数据量的机制,也能提供高效访问。
对于第二个问题,一般采取数字签名的方法,要么通过数字证书签名,要么通过像md5的方式,这就需要SSO系统返回免登URL的时候对需验证的参数进行md5加密,并带上token一起返回,最后需免登的系统进行验证信任关系的时候,需把这个token传给SSO系统,SSO系统通过对token的验证就可以辨别信息是否被改过。

posted @ 2013-01-22 18:07  行者吴江  阅读(1039)  评论(2编辑  收藏  举报