菜鸟-手把手教你把Acegi应用到实际项目中(12)-Run-As认证服务

有这样一些场合,系统用户必须以其他角色身份去操作某些资源。例如,用户A要访问资源B,而用户A拥有的角色为AUTH_USER,资源B访问的角色必须为AUTH_RUN_AS_DATE,那么此时就必须使用户A拥有角色AUTH_RUN_AS_DATE才能访问资源B。尽管这种场合相对较少,但存在即合理,总会有需要的时候,要学会未雨绸缪。
      为了实现这一需求,Acegi为我们提供了Run-As认证服务。下面我们举例说明如何应用Run-As认证服务。

1、用于配置Run-As认证服务的接口与实现类

  1. public interface IRunAsDate {
  2. public void showDate();
  3. }
  4. public class RunAsDate implements IRunAsDate {
  5. private static final Log log = LogFactory.getLog(RunAsDate.class);
  6. /* (non-Javadoc)
  7. * @see sample.service.IRunAsDate#showDate()
  8. */
  9. public void showDate() {
  10. log.info("当前日期: " + new Date());
  11. }
  12. }
public interface IRunAsDate {
public void showDate();
} public class RunAsDate implements IRunAsDate {
private static final Log log = LogFactory.getLog(RunAsDate.class); /* (non-Javadoc)
* @see sample.service.IRunAsDate#showDate()
*/
public void showDate() {
log.info("当前日期: " + new Date());
}
}

2、对showDate方法进行授权
      设置访问showDate方法必须拥有AUTH_RUN_AS_DATE角色,同时暴露IRunAsDate接口。

  1. <bean id="runAsDateImpl"
  2. class="org.springframework.aop.framework.ProxyFactoryBean">
  3. <property name="proxyInterfaces">
  4. <value>sample.service.IRunAsDate</value>
  5. </property>
  6. <property name="interceptorNames">
  7. <list>
  8. <idref local="runAsDateSecurity" />
  9. <idref local="runAsDateTarget" />
  10. </list>
  11. </property>
  12. </bean>
  13. <bean id="runAsDateTarget" class="sample.service.impl.RunAsDate"></bean>
  14. <bean id="runAsDateSecurity"
  15. class="org.acegisecurity.intercept.method.aopalliance.MethodSecurityInterceptor">
  16. <property name="alwaysReauthenticate" value="true" />
  17. <property name="authenticationManager" ref="authenticationManager" />
  18. <property name="accessDecisionManager"
  19. ref="httpRequestAccessDecisionManager" />
  20. <property name="objectDefinitionSource">
  21. <value>
  22. sample.service.IRunAsDate.showDate=AUTH_RUN_AS_DATE
  23. </value>
  24. </property>
  25. </bean>
<bean id="runAsDateImpl"
class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="proxyInterfaces">
<value>sample.service.IRunAsDate</value>
</property>
<property name="interceptorNames">
<list>
<idref local="runAsDateSecurity" />
<idref local="runAsDateTarget" />
</list>
</property>
</bean> <bean id="runAsDateTarget" class="sample.service.impl.RunAsDate"></bean> <bean id="runAsDateSecurity"
class="org.acegisecurity.intercept.method.aopalliance.MethodSecurityInterceptor">
<property name="alwaysReauthenticate" value="true" />
<property name="authenticationManager" ref="authenticationManager" />
<property name="accessDecisionManager"
ref="httpRequestAccessDecisionManager" />
<property name="objectDefinitionSource">
<value>
sample.service.IRunAsDate.showDate=AUTH_RUN_AS_DATE
</value>
</property>
</bean>

其中,alwaysReauthenticate为true表示每次操作都需要进行身份的验证。在默认情况下,RunAsManagerImpl构建的RunAsUserToken认证对象都是已认证状态。因此,只有设置alwaysReauthenticate为true时,才会触发RunAsImplAuthenticationProvider的认证操作。

3、配置RunAsImplAuthenticationProvider
      RunAsManagerImpl实例会基于现有的的已认证对象创建新的RunAsUserToken认证类型,而RunAsImplAuthenticationProvider要负责这一认证类型的认证工作。与其他认证提供者一样,必须将其加入authenticationManager中。

  1. <bean id="runAsImplAuthenticationProvider"
  2. class="org.acegisecurity.runas.RunAsImplAuthenticationProvider">
  3. <property name="key" value="javaee" />
  4. </bean>
  5. <bean id="authenticationManager"
  6. class="org.acegisecurity.providers.ProviderManager">
  7. <property name="providers">
  8. <list>
  9. ……
  10. <!-- 配置与daoAuthenticationProvider类似 -->
  11. <ref bean="runAsImplAuthenticationProvider" />
  12. </list>
  13. </property>
  14. </bean>
<bean id="runAsImplAuthenticationProvider"
class="org.acegisecurity.runas.RunAsImplAuthenticationProvider">
<property name="key" value="javaee" />
</bean> <bean id="authenticationManager"
class="org.acegisecurity.providers.ProviderManager">
<property name="providers">
<list>
……
<!-- 配置与daoAuthenticationProvider类似 -->
<ref bean="runAsImplAuthenticationProvider" />
</list>
</property>
</bean>

4、配置RunAsManagerImpl
      RunAsManagerImpl中的key必须与RunAsImplAuthenticationProvider中的key一致,从而保证RunAsManagerImpl 与RunAsImplAuthenticationProvider协同工作。在前面章节中,对于匿名认证与Remember-Me认证中也需要提供类似的key属性值。
      RunAsManagerImpl的rolePrefix属性默认值为ROLE_。由于我们配置的资源需要的角色为AUTH_RUN_AS_DATE,故在此我们将前缀设置为AUTH_。

  1. <bean id="runAsManagerImpl"
  2. class="org.acegisecurity.runas.RunAsManagerImpl">
  3. <property name="key" value="javaee" />
  4. <property name="rolePrefix" value="AUTH_" />
  5. </bean>
  6. <bean id="contactManagerSecurity"
  7. class="org.acegisecurity.intercept.method.aopalliance.MethodSecurityInterceptor">
  8. <property name="authenticationManager" ref="authenticationManager" />
  9. <property name="accessDecisionManager"
  10. ref="httpRequestAccessDecisionManager" />
  11. <property name="runAsManager" ref="runAsManagerImpl" />
  12. <property name="objectDefinitionSource">
  13. <value>
  14. ……
  15. sample.service.IContactManager.getAll=AUTH_FUNC_ContactManager.getAll,RUN_AS_DATE
  16. ……
  17. </value>
  18. </property>
  19. </bean>
<bean id="runAsManagerImpl"
class="org.acegisecurity.runas.RunAsManagerImpl">
<property name="key" value="javaee" />
<property name="rolePrefix" value="AUTH_" />
</bean> <bean id="contactManagerSecurity"
class="org.acegisecurity.intercept.method.aopalliance.MethodSecurityInterceptor">
<property name="authenticationManager" ref="authenticationManager" />
<property name="accessDecisionManager"
ref="httpRequestAccessDecisionManager" />
<property name="runAsManager" ref="runAsManagerImpl" />
<property name="objectDefinitionSource">
<value>
……
sample.service.IContactManager.getAll=AUTH_FUNC_ContactManager.getAll,RUN_AS_DATE
……
</value>
</property>
</bean>

我们对getAll方法配置了RUN_AS_DATE角色,默认时RunAsManagerImpl会从授权信息中获得前缀为”RUN_AS”的角色,同时构建新的授权信息,将rolePrefix添加到角色中,即组成类似AUTH_RUN_AS_DATE的角色。
 注意,Run-As认证服务只是临时性替换了现有用户的身份,这一点要比较重视。

5、数据库脚本
 本例采用了MySQL数据库,脚本在WebRoot/db目录下。

6、其他说明
开发环境:
MyEclipse 5.0GA
Eclipse3.2.1
JDK1.5.0_10
tomcat5.5.23
acegi-security-1.0.7
Spring2.0

Jar包:
acegi-security-1.0.7.jar
commons-codec.jar
jstl.jar(1.1)
spring.jar(2.0.8)
standard.jar
commons-logging.jar(1.0)
c3p0-0.9.0.jar
log4j-1.2.13.jar
mysql-connector-java-3.1.10-bin.jar

上一篇:201621123018《Java程序设计》第5周学习报告


下一篇:快速幂