天乙通行证是一个单点登录系统(Single sign on),用户登录一次通行证,即可以直接使用社区、Blog等产品,无需再次注册或登录,保证几个产品用户的统一,但天乙通行证由于本身没有产品化,所以现在没有开源,如果使用天乙社区需要做用户整合,只要实现通行证的类似系统就可以。
SSO的实现技术有多种,也有一些开源产品,而天乙通行证使用的是比较简单,但非常有效的方案,即同域名下的Cookie方式,实现用户的单点登录。
以天乙通行证为例,天乙社区(bbs.laoer.com)、天乙Blog(blog.laoer.com)都运行在laoer.com域名下,用户在www.laoer.com上注册后登录,通行证就会在用户的客户端写入两个Cookie,一个是用户名(Cookie名:PASS_USERNAME),一个是加密的用户名(Cookie名:PASS_USERNAME_DES),加密的方式采用3DES,采用3DES加密是因为3DES可逆的加密算法,即对密文可以还原,Cookie的Domain为.laoer.com,这样在laoer.com下的所有域名都可以访问到这个Cookie。
接下来我们说一下社区的认证过程,社区采用Struts2的MVC结构,在Action之前,都会执行一个拦截器(UserSessionInterceptor),这个拦截器首先会读取通行证的两个Cookie,如果两个Cookie都存在,则对加密的用户名进行解密,采用的密钥与通行证加密的密钥一致,然后解密后的用户名与另一个明文的用户名比对,如果两个值一致,说明用户已经在通行证登录,则建立在社区的Session(如果Session已经存在,则认为用户在社区也已经登录),如果通行证的Cookie不存在或是用户比对错误,则认为用户没有登录或已经签退,社区会做游客登录,详细处理流程请阅读UserSessionInterceptor.java源码。
如果用户在现有系统上整合社区,只要顶层域写入两个Cookie,在社区后台中有设置通行证的项目,两个系统采用的密钥一致就行了,同时3DES算法可以用多种语言实现,比如.NET、Ruby等等,所以可以在编程语言异构的网络系统中无缝使用,当然用户也可以采用自己的加密解密算法。
这个方案要注意的问题:
1、只能使用在一个主域名下,如果要跨域名则不能实现。
2、需要用户支持Cookie。
3、密钥安全性,由于所有应用都使用统一的密钥,需要在加强管理,定期更换,或是采用RSA方法对密钥加密,减少密钥泄漏的可能性。
4、对于非WEB系统,比如客户端程序,需要扩展其他方法实现。
SSO的实现技术有多种,也有一些开源产品,而天乙通行证使用的是比较简单,但非常有效的方案,即同域名下的Cookie方式,实现用户的单点登录。
以天乙通行证为例,天乙社区(bbs.laoer.com)、天乙Blog(blog.laoer.com)都运行在laoer.com域名下,用户在www.laoer.com上注册后登录,通行证就会在用户的客户端写入两个Cookie,一个是用户名(Cookie名:PASS_USERNAME),一个是加密的用户名(Cookie名:PASS_USERNAME_DES),加密的方式采用3DES,采用3DES加密是因为3DES可逆的加密算法,即对密文可以还原,Cookie的Domain为.laoer.com,这样在laoer.com下的所有域名都可以访问到这个Cookie。
接下来我们说一下社区的认证过程,社区采用Struts2的MVC结构,在Action之前,都会执行一个拦截器(UserSessionInterceptor),这个拦截器首先会读取通行证的两个Cookie,如果两个Cookie都存在,则对加密的用户名进行解密,采用的密钥与通行证加密的密钥一致,然后解密后的用户名与另一个明文的用户名比对,如果两个值一致,说明用户已经在通行证登录,则建立在社区的Session(如果Session已经存在,则认为用户在社区也已经登录),如果通行证的Cookie不存在或是用户比对错误,则认为用户没有登录或已经签退,社区会做游客登录,详细处理流程请阅读UserSessionInterceptor.java源码。
如果用户在现有系统上整合社区,只要顶层域写入两个Cookie,在社区后台中有设置通行证的项目,两个系统采用的密钥一致就行了,同时3DES算法可以用多种语言实现,比如.NET、Ruby等等,所以可以在编程语言异构的网络系统中无缝使用,当然用户也可以采用自己的加密解密算法。
这个方案要注意的问题:
1、只能使用在一个主域名下,如果要跨域名则不能实现。
2、需要用户支持Cookie。
3、密钥安全性,由于所有应用都使用统一的密钥,需要在加强管理,定期更换,或是采用RSA方法对密钥加密,减少密钥泄漏的可能性。
4、对于非WEB系统,比如客户端程序,需要扩展其他方法实现。