整合 DWR 和 Acegi 是为了保护 bean 方法调用

在此之前有必须熟悉 spring 和 acegi,我就不解释 acegi 的配置了,您可以从 acegi 网站下载最新版本。

问题提出

我们必须保护一个 bean,通过 DWR 设置“exposed”。

Acegi 是一个基于 Spring 的安全机制的框架,这个例子告诉你如何去阻止通过网页访问一个 bean 方法,
如果它没有权限的。

在 dwr.xml 里,在没有 acegi 保护下,我们这样声明 bean

<create creator="spring" javascript="loanDWR" beanName="loanDWR">
<include method="addLoan" />
</create>

在 Spring 配置文件里,这个 addLoan 方法被网页调用,这个 loadDWR bean 是一个 Spring 管理的 bean

<bean id="loanDWR" class="fr.iremia.jlab.web.dwr.LoanDWR">
	<property name="personDAO">
		<ref bean="personDAO" />
	</property>
	<property name="loanDAO">
		<ref bean="loanDAO" />
	</property>
</bean>
解决方案

然后我们怎么去阻止没有权限的访问 loanDWR.addLoan 这个方法呢?如下所示:

- 创建一个安全机制的拦截器

<bean id="loanDWRSecurityInterceptor"
	class="net.sf.acegisecurity.intercept.method.aopalliance.MethodSecurityInterceptor">
<property name="authenticationManager" ref="authenticationManager" />
<property name="accessDecisionManager" ref="httpRequestAccessDecisionManager" />
<property name="objectDefinitionSource">
	<value>fr.iremia.jlab.web.dwr.LoanDWR.addLoan=edit,admin</value>
</property>
</bean>

LoanDWR.addLoan 方法,只能被管理员或者有修改角色权限的用户 edit 调用

想要了解 acegi 的属性:authenticationManager 和 httpRequestAccessDecisionManager,请参考
http://acegisecurity.org/docbook/acegi.html

- 为 bean 创建一个代理
给原有的 loanDWR Spring bean 添加一个代理,使用 Spring proxyfactorybean:

<bean id="loanDWRSecure" class="org.springframework.aop.framework.ProxyFactoryBean">
	<property name="target" ref="loanDWR" />
	<property name="interceptorNames">
		<idref local="loanDWRSecurityInterceptor" />
	</property>
</bean>

现在,loadDWRSecure 是个代理被 loanDWR 调用,每个调用 addLoan 方法将被 Acegi 拦截,只有拥有权限的用户才能调用

- 修改 dwr 配置文件

我们现在需要修改

<create creator="spring" javascript="loanDWR" beanName="loanDWRSecure">
	<include method="addLoan" />
</create>