Java学习者论坛

 找回密码
 立即注册

QQ登录

只需一步,快速开始

手机号码,快捷登录

恭喜Java学习者论坛(https://www.javaxxz.com)已经为数万Java学习者服务超过8年了!积累会员资料超过10000G+
成为本站VIP会员,下载本站10000G+会员资源,购买链接:点击进入购买VIP会员
JAVA高级面试进阶视频教程Java架构师系统进阶VIP课程

分布式高可用全栈开发微服务教程

Go语言视频零基础入门到精通

Java架构师3期(课件+源码)

Java开发全终端实战租房项目视频教程

SpringBoot2.X入门到高级使用教程

大数据培训第六期全套视频教程

深度学习(CNN RNN GAN)算法原理

Java亿级流量电商系统视频教程

互联网架构师视频教程

年薪50万Spark2.0从入门到精通

年薪50万!人工智能学习路线教程

年薪50万!大数据从入门到精通学习路线年薪50万!机器学习入门到精通视频教程
仿小米商城类app和小程序视频教程深度学习数据分析基础到实战最新黑马javaEE2.1就业课程从 0到JVM实战高手教程 MySQL入门到精通教程
查看: 1433|回复: 0

J2EE-单点登陆源码 下载

  [复制链接]
  • TA的每日心情
    开心
    2021-3-12 23:18
  • 签到天数: 2 天

    [LV.1]初来乍到

    发表于 2011-9-16 10:28:01 | 显示全部楼层 |阅读模式
    http://blog.chinaunix.net/u1/52224/showart_410119.html中讲到系统的权限控制模型,当时按照最小依赖和最大重用把web系统权限控制划分成了业务逻辑、权限管理、权限验证、登陆代理、登陆服务、用户管理、业务逻辑数据库、业务权限数据库和用户数据库几个部分,现在开始逐一实现以上除业务逻辑的部分,今天发布的是单点登陆系统,也就是登陆代理和登陆服务。
    基于COOKIE的单点登陆
    单点登陆就是只需要在访问第一个业务逻辑时输入用户验证信息,以后访问其他业务逻辑不需要再次输入用户验证信息,而不管业务逻辑的部署方式。
    要实现单点登陆,其实就是要让系统有记忆功能,能记住用户以前登陆过,下次登陆时就不再需要用户输入身份验证信息,就像有的论坛会让用户选择记住用户登陆状态,并且可以选择一个过期时间,这样在过期时间之内用户访问这个论坛,论坛会标记用户为已登陆状态。
    [/td][td=1,1,342]
    Google_protectAndRun("render_ads.js::google_render_ad", google_handleError, google_render_ad);
    [/td][/tr][/table]

    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截获了正常用户A的SESSION COOKIE,然后B访问业务逻辑时附带这个COOKIE,Web应用服务器会认为B就是A,于是A能得到的用户凭证,B也能得到,B就成了A的影子,与A具有相同的操作权限。所以关键问题还是如何避免SESSION COOKIE的泄露,因为这个COOKIE由Web应用服务器控制,所以除了在网络传输时使用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变成数据b,b通常数据长度固定并且很小,而且不能用过b反运算得到a,常用的数字摘要算法有MD5和SHA1。
    制作证书时,首先将证书信息i使用数字摘要算法如SHA1进行运算得到s,s = SHA1(i),然后把i和s使用非对称加密算法如RSA的s加密得到证书c,c = RSA(s, i+s)。获取证书信息刚好是一个逆过程,i+s = RSA(p, c),然后把i和s分离,并且比较s和SHA1(i)是否一致,如果一致,则这个证书信息是可信赖的。
    证书通常由权威机构制作,这个机构妥善保管s,公布p,那么互不相识的A和B通信,A要核对B的身份,A要求B的证书,然后核对解密后的证书信息就可以了。
    同样登陆代理和登陆服务在传递信息时也要核对身份,否则黑客可以将登陆代理引导到假冒的登陆服务,或者传递给登陆代理预先设定的用户凭证,进行认证欺骗。使用证书后,登陆代理请求登陆服务进行登陆时,首先核对登陆服务的证书,登陆代理处理登陆服务返回的用户凭证时,也核对登陆服务的证书,双方信息传递在https中进行,所以存在消息篡改和泄漏,保证登陆服务是可信赖的。登陆服务的证书必须妥善保管,并且定期更换。
    也可以根据证书原理自定义处理过程,登陆代理和登陆服务各自掌握p和s,证书代理发送消息使用p加密,接收消息使用p解密,登陆服务接收消息使用s解密,发送消息使用s加密,消息附带SHA1数字摘要,这样登陆代理和登陆服务也可相互信任。这种方案下,可以不使用https,因为消息已经被加密。但是这样有一个漏洞,就是会被重播,比如黑客可以截获登陆服务发送给登陆代理的整个加密的消息,然后完整地发送给登陆代理,这样登陆代理不能识别究竟真伪而被欺骗。可以在消息里面附加随机数据来解决这个漏洞,登陆代理发送消息前,先随机产生一段数据,并附加到消息中,然后加密发送给登陆服务,登陆服务发送消息给登陆代理时也附带这个数据,登陆代理核对这个数据来确定有效性,每次登陆代理和登陆服务传输的数据都不一样,重播不再有效。
    安装部署
    我用的版本是Tomcat5523+MySQL5037+jre1.5.0_12,没在其他版本下测试过。
    1.下载cglib最新版本http://cglib.sourceforge.net/,拷贝asm.jar和cglib-2.1.3.jar到Tomcat/shared/lib。
    2.下载c3p0最新版本http://sourceforge.net/projects/c3p0,拷贝c3p0-0.9.1.1.jar到Tomcat/shared/lib。
    3.下载mysql-connector最新版本http://sourceforge.net/projects/mmmysql/,拷贝mysql-connector-java-5.0.4-bin.jar到Tomcat/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下面生成sso和ssoagent两个目录,分别对应登陆服务和登陆代理,停止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
    下载:下载


    下载地址:

    J2EE-单点登陆源码 下载
    回复

    使用道具 举报

    该用户从未签到

    发表于 2011-10-10 13:18:59 | 显示全部楼层
    谢谢楼主分享啊 。。
    回复 支持 反对

    使用道具 举报

    该用户从未签到

    发表于 2012-3-9 09:48:19 | 显示全部楼层
    ok
    回复 支持 反对

    使用道具 举报

    该用户从未签到

    发表于 2012-3-17 11:09:51 | 显示全部楼层
    呵,呵,好东西!谢谢了
    回复 支持 反对

    使用道具 举报

    该用户从未签到

    发表于 2012-3-28 00:26:31 | 显示全部楼层
    学习了
    回复 支持 反对

    使用道具 举报

    该用户从未签到

    发表于 2012-4-20 15:08:29 | 显示全部楼层
    谢谢  学习一下
    回复 支持 反对

    使用道具 举报

    该用户从未签到

    发表于 2012-11-22 14:04:51 | 显示全部楼层
    我现在在做的项目就是单点登录,。谢谢楼主的无私精神
    回复 支持 反对

    使用道具 举报

    该用户从未签到

    发表于 2012-11-22 19:13:15 | 显示全部楼层
    J2EE-单点登陆源码 下载 [修改]
    回复 支持 反对

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    QQ|手机版|Java学习者论坛 ( 声明:本站资料整理自互联网,用于Java学习者交流学习使用,对资料版权不负任何法律责任,若有侵权请及时联系客服屏蔽删除 )

    GMT+8, 2025-1-24 04:57 , Processed in 0.405802 second(s), 50 queries .

    Powered by Discuz! X3.4

    © 2001-2017 Comsenz Inc.

    快速回复 返回顶部 返回列表