Posted on 2007-03-07 13:00
云自无心水自闲 阅读(1632)
评论(0) 编辑 收藏 所属分类:
Java 、
心得体会 、
Acegi
Acegi提供了一个优秀的基于J2EE企业级应用的安全认证机制。尤其是对于Spring框架的支持,在J2EE的企业软件开发解决方案中是领先的。
来看一下Acegi的重要的共享组件。如果组件是框架的核心而且一旦缺少这些组件框架将无法运转,那么这些组件可以称为是“共享”的。这些Java类型是系统其他部分的基础,所以理解他们是十分重要的,虽然你可以并不会直接与之互动。
其中最基础的对象是SecurityContextHolder,用于存储应用安全上下文的细节信息。缺省情况下,SecurityContextHolder使用ThreadLocal来存储信息,这意味着安全上下文对于同一个线程的所有方法都是有效的。有一些应用不适合使用ThreadLocal,比如:一个Swing的客户端可能希望所有JVM所有的线程都使用相同的安全上下文。对于这种情况,你可以用SecurityContextHolder.MODE_GLOBAL。你可以把SecurityContextHolder从缺省模式MODE_THREADLOCAL改变为MODE_GLOBAL。
在SecurityContextHolder中存储了与应用互动的规则。Acegi使用Authentication对象来表示这些信息。这并不是需要你自己创建Authentication对象,更通常的做法是查询到一个Authentication对象。举例如下,在应用的任何一个地方都可以这样使用:
Object obj = SecurityContextHolder.getContext().getAuthentication().getPrincipal();
if( obj instanceof UserDetails){
String username=((UserDetails)obj).getUsername();
}else{
String username=obj.toString();
}
上面这段代码介绍了不少有意思的对象和关系。首先,大家会发现在SecurityContextHolder和Authentication之间存在着一个即时对象:SecurityContext,SecurityContextHolder.GetContext()返回的类型就是SecurityContext。Acegi有数个SecurtiyContext的实现。
另一个值得注意的是我们从Authentication中获得了一个规则。这个规则的类型是:Object。大多数情况下,我们可以把它强制性转换成UserDetails对象。UserDetails是Acegi的核心接口。它代表了一种规则,但是经过了应用相关的扩展。可以把UserDetails想象成为应用数据库与Acegi的SecurityContextHolder需要的两者之间的适配器(Adapter)。如果作为应用自己的数据库的代表,那么可以把UserDetails强制性转换为其原始类,这样,你就可以调用其中的业务方法(比如:getEmail()等等)。
那么,为什么要提供一个UserDetails对象呢?是这样的:有一个特殊的接口:UserDetailsService,这个接口只有一个方法,这个方法接收一个String类型的表示用户名的参数,返回UserDetails对象。大多数认证提供provider装配一个代理到UserDetailsService上。UserDetailsService被用于创建SecurityContextHolder中存储的Authentication对象。Acegi中提供了若干个UserDetailsService的实现,一个使用内存Map,一个用JDBC。大多数用户倾向于写一个自己的实现,通常是使用DAO。不论UserDetailsService返回的是什么,都可以通过SecurityContextHolder获得。
Authentication提供另一个重要的方法是getAuthorites()。这个方法返回一个GrantedAuthority对象的数组。GrantedAuthority是授权给的认证。这个认证通常指的是“角色”,比如:ROLE_ADMINISTRATOR或者ROLE_HR_SUPERVISOR。这些角色需配置用于web认证,方法认证和域对象认证。如果Acegi的其他部分希望看到这些认证,那么UserDetailsService返回GrantedAuthority对象即可。
最后,有时你需要在HTTP requests之间传递SecurityContext,有时每次请求都需要重新认证。那么可以使用HttpSessionContextIntergrationFilter,这是用于在HTTP Request之间传递SecurityContext的东东。就象名称所表示的那样:HttpSession用于存储这些信息。但是你不需要直接操作HttpSession。