推荐:J2EE中用户授权和SSO(单点登录)

今天才看到这篇文章,非常好,从各个方面阐述了J2EE中用户验证系统的原理和应用技术,其中关于JAAS和Petstore的论述很精彩,文章考证了Petstore的三个版本中不同用户系统的实现:

1.Java Pet Store 1.0.1
使用form-based authentication ,表单式认证,这是我们常用的,但用户到达一个不被授权访问的资源时,web容器就推出一个html页面,要求输入用户名和密码,缺点:not portable across containers.

2.Java Pet Store 1.1.2
一个基于servlet的sign in/sign out来集中处理所有的request,缺点是必须由应用程序自己来处理。

3.Java Pet Store 1.3
使用filter概念来防止用户访问一些被授权的资源,filter会截取所有的request/response,然后放置一个验证通过的标识在用户的session中,然后filter每次依靠这个标识来决定是否放行response.
但是也是没有使用Jaas。

文章认为,我们必须使用Jaas,这样才能开发出一个可重用 可移植的健壮的用户权限系统。

文章开始分析几个很好的用户权限系统:
M$的.net的Passport
Netegrity SiteMinder
IBM WebSphere Portal Server
IBM是使用写加密的key到用户浏览器cookiet中的办法实现跨域名验证。

文章最后提出SSO模式:
这个模式分为:
gatekeeper :采取filter 或统一servlet的方式
authenticator: 在WEB中使用JAAS自己来实现。
用户资格存储: LDAP或数据库

1.gatekeeper拦截检查每个到达受保护的资源。首先检查这个用户是否有已经创建好的login session,如果没有,gatekeeper 检查是否有一个全局的和authenticator相关的SSO session?

2.如果没有全局的SSO session, 这个用户被导向到authenticator的 sign-on 页面,要求提供用户名和密码。

3.authenticator接受用户名和密码,通过用户的资格系统验证用户。

4.如果验证成功, authenticator将创建一个全局的login session,并且导向gatekeeper来为这个用户在他的web应用中创建一个login session

5.authenticator和gatekeepers联合分享cookie,或者使用tokens在query字符里

文章地址:

http://www.javaworld.com/javaworld/jw-05-2002/jw-0524-signon.html

这篇文章的感觉怪怪的,有点中国人的论文风格

原来在一个MailList上看过一篇文章,那位程序员一开始是问怎么做 SSO.后来,他自已回了一贴,说他解决了这个问题,他利用数据库来做 Global Session. 这样,无论是 php,asp 还是 Java 写和 web 程序,都可以检验用户是否已经登录。具体内容我已经想不起,不过按照这个思路来设计,应该也不难。

主要可能遇到的问题是 Session 如何管理。
如什么时候创建?什么时候 destroy? 等等的问题。

关于"什么时候创建?什么时候 destroy? 等等的问题。"
正是SSO模式的gatekeeper 和authoration两个部分解决的,那位程序员的方案只解决了"用户资料存储"的功能。

iceant 提到利用数据库来做 Global Session.

我以前用 php+mysql 实现过,但是有个问题, cookie 的发送和网站(域名)有关,同一个网站下的认证可以。

举例说吧。你在 http://site1.yourcompany.com/ 认证后,登录信息被保存在数据库中,并且信息也用 cookie 形式返回给 browser,下次你再连接 http://site1.yourcompany.com/somepath/somepage.whatever 时, cookie 信息被 browser 返回给你,但是如果你浏览 http://site2.yourcompany.com/somepath/somepage.whatever, browser 并不发送刚才保存的 cookie。

前一段时间我一直在研究如何在 INTRANET 内实现 WEB 应用 + Windows Domain 的SSO方案。

现在我使用了 NTLM 协议,在samba 上有个项目,可以直接使用,但是对windows 98 支持不好,要求Windows NT以上的机器。

因为是内联网,所以这些要求很容易满足。

因为 NTLM 相比 Kerberos 有些不足之处,所以,我会抽时间去实现 Kerberos 的方案。这会比较花时间,因为 SPNEGO-GSS 只有一家公司实现了(很贵),而且也没有相应的规范出台,JavaOne 上说准备实现,但是也不知道是哪一年以后的事了。

Kerberos 相比 NTLM 对客户端的要求又高了一点,要求是 Windows 2K 以上版本的Windows. 但是它的安全性及方便性是不容置疑的。

以前实现过在java中利用windows的登录:
IIS下面安装tomcat/resin, 然后设置IIS为域用户登录. 这样在servlet中就可以取得remote_user. 这种方案在编程上简单些 :)

问题是总得有一台 Windows 的服务器,好麻烦

那这个全局Session又如何维护呢?不应该只是简单地设一个超时值,然后加一个会话绑定负责维护数据库中的session记录。因为只要用户至少在一个应用服务器上的会话没过期,那么这个用户的全局会话就不应该过期。希望能给个思路。另外就是楼主给的链接:http/www.jdon.com/download/SecurityPatterns.pdf 不好用。
多谢了!

是否可以考虑结合LDAP来实现?

我说的SSO不只限于 web 系统,我希望做到这样的效果,如:用户使用 Web Based Workflow 系统时,系统提示用户输入用户名和密码。当用户在 Workflow 里处理完业务后,它又在控制端使用 Telnet 来访问另一种资源,这时,telnet server 能利用 User 在使用 Workflow 时的登录信息,直接对用户进行认证与授权,不再提示用户名与密码的输入。

相反,如果用户先使用了 Telnet 服务,然后再来使用 Web 服务,也应该不再需要输入用户名与密码。

sso应该支持不同语言写的程序,运行在不同平台上的程序,b/s和c/s的程序,这对系统集成很重要

SSO是门户的基础,我们公司现在正在筹备这方面的项目

原本是打算自己做,后来和BEA和SUN做过技术交流以后,决定用SUN的SUN ONE SERVER来做

其实SSO的基本原理很简单,我们在考虑自己实现的时候,遇到一些技术难题,后来和BEA、SUN做过交流后才证实了我们的一些想法:

SSO最简单,最直接的实现方法是基于COOKIE,性能最高
基于COOKIE最大的难点在于跨域
SSO的核心在于统一用户认证,而这个从实现层面上就可以看作一个认证服务器,也真是SUN公司所推崇的IDENTITY SERVER,所以的登录、认证请求都在这里完成,然后分发到相应应用
而他们解决COOKIE跨域的方法也是基于这个IDENTITY SERVER的,用户登陆后可以在各个他所访问的域内写COOKIE,而这些COOKIE都是IDENTITY SERVER所可以认证的,由此做到松散的集群制。

如果大家有兴趣自己实现,也可以基于这个实现,无非是在COOKIE中建立只有自己的IDENTITY SERVER可认证的串,通过重定向方式到IDENTITY SERVER验证,然后返回认证结果,操作功能,由于COOKIE内容的一致性致使跨域成为可能

当然SUN所做的远比我说说的复杂,比如每个认证的域都需安装它所提供的认证软件等等,不过基本实现就是这样的

SSO现在是做企业应用的基础,大的运营商在理性化建设的基础上都想整合原有应用,所以门户是他们最关心的,而SSO是第一步

希望大家批评指正

IBM的Protal有比较好的解决方案,但protal server实在太贵了,一般用户估计承受不了:P