J2EE-单点登陆

来源:http://blog.chinaunix.net/u1/52224/showart_412714.html

 

http://blog.chinaunix.net/u1/52224/showart_410119.html 中讲到系统的权限控制模型,当时按照最小依赖和最大重用把web 系 统权限控制划分成了业务逻辑、权限管理、权限验证、登陆代理、登陆服务、用户管理、业务逻辑数据库、业务权限数据库和用户数据库几个部分,现在开始逐一实 现以上除业务逻辑的部分,今天发布的是单点登陆系统,也就是登陆代理和登陆服务。
 

基于COOKIE 的单点登陆

      单点登陆就是只需要在 访问第一个业务逻辑时输入用户验证信息,以后访问其他业务逻辑不需要再次输入用户验证信息,而不管业务逻辑的部署方式。
      要实现单点登陆,其实 就是要让系统有记忆功能,能记住用户以前登陆过,下次登陆时就不再需要用户输入身份验证信息,就像有的论坛会让用户选择记住用户登陆状态,并且可以选择一 个过期时间,这样在过期时间之内用户访问这个论坛,论坛会标记用户为已登陆状态。
      COOKIE 是实现系 统记忆功能的很好的工具,COOKIE 有两种,一种成为内存COOKIE ,这种COOKIE 在 用户关闭浏览器时失效,另外一种为文件COOKIE ,可以保存在用户的电脑系 统中,并且可以设置一个过期时间,在过期时间内该COOKIE 都有效。COOKIE 的另一个特性是域,概念等同于JAVA 的包,当浏览器访问某个链接时,会把这个链接的域跟所有存在的COOKIE 的域进行对比,域匹配的COOKIE 将 被自动发送到WEB 服务器。
      根据COOKIE 的生存周期和域特性,可以在登陆服务里面设置一个COOKIE ,这个COOKIE 用 来标志用户是否已经登陆,COOKIE 可以选择内存COOKIE 或者文件COOKIE , 因为COOKIE 是域相关的,所以只有登陆服务可以看到这个COOKIE 。由于用户访问业务逻辑时,如果登陆代理找不到用户凭证,就会去登陆服务那里 登陆,这时登陆服务的策略为如果找不到这个COOKIE ,那么提示用户输入用 户验证信息验证,如果找到这个COOKIE ,那么直接告诉登陆代理已经登陆。
      流程图如下:
      用户访问某业务逻辑, 业务逻辑向登陆代理获取用户凭证。
登陆代理首先在SESSION 中查 找用户凭证,如果用户凭证存在,表明用户已经登陆过,返回用户凭证给业务逻辑,如果用户凭证不存在,则向登陆服务请求登陆。
登陆服务首先COOKIE 中查找用 户凭证,如果用户凭证存在,表明用户已经登陆过,返回用户凭证给登陆代理,如果不存在,则转向登陆页面要求用户输入用户验证信息,然后验证用户登陆信息, 验证通过后设置COOKIE 以备下次登陆请求使用。
登陆代理接收到登陆服务的返回后,解析出用户凭证,保存该用户凭证到SESSION 以备以后使用,然后返回该用户凭证给业务逻辑。
业务逻辑接收到登陆代理的用户凭证后,验证权限,验证通过处理业务逻辑相关功能。
      上面的文字解释可能有 点晕,看流程图应该比较清楚,文字解释可能只是画蛇添足。
      如果把业务逻辑和登陆 代理等中间过程透明化,只保留用户和登陆服务,那么登陆过程就非常清晰,其实就是用户访问登陆服务的过程,因为登陆服务只有一个,所以对指定的用户来说, 一旦用户登陆过,那么COOKIE 就存在,所以用户下次再访问登陆服务,那么 就不再需要输入用户名密码等用户验证信息了。
      这里可能有一个疑惑, 就是登陆代理为什么要把用户凭证保存到SESSION ?这是为了提高效率,如 果登陆代理不保存用户凭证,那么每次业务逻辑要查询用户凭证时,登陆代理都要转向登陆服务去查询,因为业务逻辑可能和登陆服务不是部署在一个地方,那么登 陆代理向登陆服务查询用户凭证的过程需要很长的等待时间,用户感觉就是系统反应迟钝。当然,也可以把用户凭证保存在业务逻辑里,但是这样业务逻辑就做了本 来不属于他的事情,所以保存在登陆代理里比较合理。因为登陆代理和业务逻辑是部署在一个WEB 应 用程序里,所以使用登陆代理的SESSION 保存用户凭证,可以保证在业务逻 辑的生存期内,用户凭证一直有效。
 

COOKIE 安全性

      COOKIE 在登陆服 务中用来保存用户凭证,在登陆代理中用来保存SESSION
      假设用户A 是正常用户,通过登陆服务进行了登陆,用户凭证被COOKIE 记录下来,假设这时黑客B 截 获了A 的用户凭证,那么当B 连接到登陆服务验证时,B 可以把截获的用户凭 证附加到COOKIE 中,因为登陆服务通过COOKIE 来判断登陆状态,所以登陆服务会认为B 以前登陆过,并且告诉登陆代理B 的用 户凭证,这样B 就欺骗了登陆服务而拥有了用户A 的操作权限。
      首先应该避免用户凭证 的COOKIE 泄露,在用户端,因为内存COOKIE 比文件COOKIE 更难 被截取,特别是经过特殊处理的浏览器,要截取内存COOKIE 几乎不可能,而 且当浏览器关闭时,内存COOKIE 失效,所以应该使用内存COOKIE 而非文件COOKIE , 这也是很多使用文件COOKIE 的论坛帐号经常被盗的原因。
      其次,为进一步减少风 险,不应该在COOKIE 中直接保存用户凭证,而是使用一个无意义的标识符如UUID 来表示,而登陆服务可以通过这个UUID 查找到真正的用户凭证,这个标志符随机生成,即使同一用户登陆,得到的UUID 也不一样,所以不能重复使用,这样即使偶尔泄露一次,也不会造成长期影响。为了提高COOKIE 的截取难度,可以设置一个有效时间,只有在有效期内的COOKIE 是合法的,超过有效期的COOKIE 将被忽略,使用超过有效期的用户依然需要重新输入验证信息。这样也带来一个不便的地方,就是用户如果两次业务逻 辑之间的切换时间超过了COOKIE 的有效期,那么用户还得重新输入验证信 息,达不到单点登陆的效果,所以如何取舍,要根据业务逻辑而定。
其次因为http 使用明文传输,通 过网络侦听的方式很容易获取COOKIE ,所以用户到登陆服务间的连接应该采 用https
      然后考察登陆代理中使 用COOKIE 来保存SESSION 的情况,这是大多数Web 应用服 务器采用的方法。这种情况类似登陆服务使用COOKIE 来保存用户凭证,典型 的欺骗是黑客B 截获了正常用户ASESSION COOKIE ,然后B 访问业务逻辑时附带这个COOKIEWeb 应用服务器会认为B 就 是A ,于是A 能 得到的用户凭证,B 也能得到,B 就成了A 的影子,与A 具有相同的操作权限。所以关键问题还是如何避免SESSION COOKIE 的泄露,因为这个COOKIEWeb 应用服务器控制,所以除了在网络传输时使用https ,基本上没有其他办法可以降低风险。除了使用COOKIE 作 为SESSION 标记,很多Web 应用服务器也支持隐式域的方式,就是Web 应 用服务器在页面自动创建一个隐藏的表单项作为SESSION 标记,页面提交时 该表单自动被提交,Web 应用服务器通过这个表单项来确定用户SESSION 。这个是更不安全的做法,因为很多很简单的方法就可以获取页面表单项的数 据,比获取内存COOKIE 容易很多。
 

消息传递安全性

      业务逻辑、登陆代理、 登陆服务间存在消息传递,业务逻辑和登陆代理部署在一个Web 应用服务器中, 消息传递比较安全。登陆代理和登陆服务通常处在不同的Web 应用服务器中,并 且通常在地域上也不一致,登陆代理和登陆服务间的安全隐患除了消息泄露,还有相互信任的问题。
      首先是消息泄露,使用https 可以避免消息泄露。
      其次是登陆代理和登陆 服务间如何相互信任,这就需要安全证书。关于证书的更多信息参考 http://en.wikipedia.org/wiki/Certificate_authority ,也可以去google 搜索。证书的原理是基于非对称加 密和数字摘要,非对称加密由一对密钥(p, s) 组成,使用p 加密的数据只能使用s 解 密,使用s 加密的数据只能使用p 解密,著名的非对称加密算法是RSA ,数字摘 要通过一个不可逆运算可以把数据a 变成数据bb 通常数 据长度固定并且很小,而且不能用过b 反运算得到a ,常用的数字摘要算法有MD5SHA1
      制作证书时,首先将证 书信息i 使用数字摘要算法如SHA1 进行运算得到ss = SHA1(i) ,然后把is 使用非对称加密算法如RSAs 加 密得到证书cc = RSA(s, i+s) 。获取证书信息刚好是一个逆过程,i+s = RSA(p, c) ,然后把is 分离,并且比较sSHA1(i) 是否一致,如果一致,则这个证书信息是可信赖的。
      证书通常由权威机构制 作,这个机构妥善保管s ,公布p ,那么互不相识的AB 通信,A 要 核对B 的身份,A 要 求B 的证书,然后核对解密后的证书信息就可以了。
      同样登陆代理和登陆服 务在传递信息时也要核对身份,否则黑客可以将登陆代理引导到假冒的登陆服务,或者传递给登陆代理预先设定的用户凭证,进行认证欺骗。使用证书后,登陆代理 请求登陆服务进行登陆时,首先核对登陆服务的证书,登陆代理处理登陆服务返回的用户凭证时,也核对登陆服务的证书,双方信息传递在https 中进行,所以存在消息篡改和泄漏,保证登陆服务是可信赖的。登陆服务的证书必须 妥善保管,并且定期更换。
      也可以根据证书原理自 定义处理过程,登陆代理和登陆服务各自掌握ps ,证书代理发送消息使用p 加 密,接收消息使用p 解密,登陆服务接收消息使用s 解密,发送消息使用s 加 密,消息附带SHA1 数字摘要,这样登陆代理和登陆服务也可相互信任。这种方 案下,可以不使用https ,因为消息已经被加密。但是这样有一个漏洞,就是 会被重播,比如黑客可以截获登陆服务发送给登陆代理的整个加密的消息,然后完整地发送给登陆代理,这样登陆代理不能识别究竟真伪而被欺骗。可以在消息里面 附加随机数据来解决这个漏洞,登陆代理发送消息前,先随机产生一段数据,并附加到消息中,然后加密发送给登陆服务,登陆服务发送消息给登陆代理时也附带这 个数据,登陆代理核对这个数据来确定有效性,每次登陆代理和登陆服务传输的数据都不一样,重播不再有效。

安装部署

我用的版本是Tomcat5523+MySQL5037+jre1.5.0_12 , 没在其他版本下测试过。
1. 下载cglib 最新版本 http://cglib.sourceforge.net/ ,拷贝asm.jarcglib-2.1.3.jarTomcat/shared/lib
2. 下载c3p0 最新版本 http://sourceforge.net/projects/c3p0 ,拷贝c3p0-0.9.1.1.jarTomcat/shared/lib
3. 下载mysql-connector 最新版本 http://sourceforge.net/projects/mmmysql/ ,拷贝mysql-connector-java-5.0.4-bin.jarTomcat/shared/lib
4. 下载profile.v1.MySQL5.sql.rar解压缩为 profile.v1.MySQL5.sql ,导入到MySQL 数 据库中。
  创建用户,用户名root,密码1

insert into T_PROFILE( USER_NAME, USER_PASSWORD) values ( 'root' , sha1( '1' ) ) ;

5. 下载sso.rar解压缩为sso.war ,这个是登陆服务,复制到Tomcat/webapps ,下载ssoagent.rar解压缩为ssoagent.war ,这个是登陆代理,里面附带简单的业务逻辑,复制到Tomcat/webapps ,启动tomcat ,这时Tomcat/webapps 下 面生成ssossoagent 两 个目录,分别对应登陆服务和登陆代理,停止tomcat
 
6. 找到Tomcat/webapps/sso/WEB-INF/classes/sso_passport.properties
      # 修改为你的实际的/sso/passport/authen.jsp 的路径。
      sso.passport.authenUrl =http://bsmith-cn:8080/sso/passport/authen.jsp
      # 修改为你的实际的profile 数据库的url
      sso.passport.db.ds.c3p0.url =jdbc:mysql://localhost/profile
      # 修改为你的实际的profile 数据库用户名
      sso.passport.db.ds.c3p0.user =root
      # 修改为你的实际的profile 数据库密码
      sso.passport.db.ds.c3p0.password =1
 
7.  找到Tomcat/webapps/ssoagent/WEB-INF/classes/sso_agent.properties
      # 修改为你的实际的/sso/passport/login.srv 路径
      sso.passport.login =http://bsmith-cn:8080/sso/passport/login.srv
      # 修改为你的实际的/sso/passport/logout.srv 路径
      sso.passport.logout =http://bsmith-cn:8080/sso/passport/logout.srv
 
8. 启动Tomcat ,输入 http://yourhost:yourport/ssoagent/logic/index.jsp 测试,如果配置成功,将看到测试页面的几个业务逻辑,业务逻辑本身什么也不干,只是验证登陆有效性,有的业务逻辑需要登陆才能访问, 有的不需要登陆就能访问。
 
 
文件:sso.rar
大小:30KB
下载:下 载
文件:ssoagent.rar
大小:21KB
下载:下 载
文件:profile.v1.MySQL5.sql.rar
大小:0KB
下载:下 载
文件:sso.passport.src.v1.jar.rar
大小:56KB
下载:下 载
文件:ssoagent.src.v1.jar.rar
大小:36KB
下载:下 载
 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值