2012-01-30 75 views
3

以下问题已经把我逼疯:@Secured注释工作,但@PostAuthorize与PermissionEvaluator不

我有以下设置:

  • 接口StudyService
  • @Service StudyServiceImpl实现StudyService
  • @Controller StudyServiceController实现StudyService
  • SampleDAOImpl实现SampleDAO
  • 一个permissionEvaluator CdmPermissionEvaluator

我有以下代码:

class SampleDAOImpl implements SampleDAO { 
... 
    @Secured(Roles.USER) 
    @PostAuthorize("hasPermission(returnObject, 'read')") 
    Sample load(long sampleId) { 
     ... 
    } 
... 
} 

的@Secured的作品,因为我有登录时出现。然而,@PostAutorize不起作用,即使我将@Secured注释掉。我在CdmPermissionEvaluator.hasPermission()中有一个日志语句,并且它永远不会被记录。当我注释掉@Secured注释(以避免由于默认的AffirmativeBased投票者而未获得评估@PostAuthorize)时,情况也是如此。

web.xml中的相关部分:

... 
<filter> 
    <filter-name>springSecurityFilterChain</filter-name> 
    <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class> 
</filter> 
<filter-mapping> 
    <filter-name>springSecurityFilterChain</filter-name> 
    <url-pattern>/*</url-pattern> 
</filter-mapping> 
... 
<servlet> 
    <servlet-name>spring</servlet-name> 
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> 
    <load-on-startup>1</load-on-startup> 
</servlet> 
<servlet-mapping> 
    <servlet-name>spring</servlet-name> 
    <url-pattern>*.rpc</url-pattern> 
</servlet-mapping> 
... 

弹簧servlet.xml中的相关部分:

applicationContext.xml中的
... 
<security:global-method-security secured-annotations="enabled"/> 
<context:annotation-config/> 

<!-- Auto-detect controllers; these extend RemoteServiceServlet and are --> 
<!-- annotated with @Controller --> 
<context:component-scan base-package="org.gmeb.crf.server"> 
    <context:include-filter type="annotation" 
       expression="org.springframework.stereotype.Controller"/> 
</context:component-scan> 
... 

相关部分:

<context:annotation-config/> 

<bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"/> 

<context:component-scan base-package="org.gmeb.crf"> 
    <context:exclude-filter type="annotation" 
       expression="org.springframework.stereotype.Controller"/> 
</context:component-scan> 

相关部分applicationContext-security.xml:

<http auto-config="true" entry-point-ref="authenticationEntryPoint" 
     create-session="always" use-expressions="true"> 
    <intercept-url pattern="/**" access="permitAll()"/> 
    <form-login authentication-success-handler-ref="authenticationSuccessHandler" 
       authentication-failure-handler-ref="authenticationFailureHandler"/> 
    <logout success-handler-ref="logoutSuccessHandler"/> 
    <anonymous/> 
</http> 
... 
<global-method-security pre-post-annotations="enabled"> <!-- TODO: Add proxy-target-class="true" --> 
    <expression-handler ref="expressionHandler"/> 
</global-method-security> 

<beans:bean id="expressionHandler" 
      class="org.springframework.security.access.expression.method.DefaultMethodSecurityExpressionHandler"> 
    <beans:property name="permissionEvaluator" ref="cdmPermissionEvaluator"/> 
</beans:bean> 

<beans:bean id="loggerListener" 
      class="org.springframework.security.authentication.event.LoggerListener"/> 

<context:annotation-config/> 

<beans:bean id="cdmPermissionEvaluator" class="org.gmeb.crf.server.auth.CdmPermissionEvaluator"> 
</beans:bean> 

任何想法我在这里做错了吗?

在我进行此设置之前,我在@Service StudyServiceImpl中使用了@PostAuthorize注释,并使用Spring EL表达式(无permissionEvaluator),并且工作正常。那么我做错了什么,和以前的设置有什么不同?

由于提前,

阿尔诺

+0

经过几天的讨论,我发现问题在于:spring-servlet.xml已经获得了annotations =“enabled”,但是没有pre-post-annotations =“enabled”。如果我理解正确,我可以从applicationContext-security.xml中删除标记,因为它实际上是来自spring-servlet.xml的标记,它正在被使用。另外,我在spring-servlet.xml中加载了@@ Controllers,而在applicationContext.xml中加载了其余的部分。我是否也可以从spring-servlet.xml加载@@ Services,而从applicationContext.xml加载所有其他的? – user1178488 2012-01-31 10:33:34

回答

1

这是行不通的,因为你不能没有得到奇怪的结果在一个单一的方法混合使用不同的注释类型。因此,建议您坚持为每个想要保护的类或接口选择一个“安全元数据”选项。

更详细地说,可以在应用程序中使用多个不同的元数据源(安全注释,预先注释注释,切入点定义,JSR-250注释)。它们通常由一个DelegatingMethodSecurityMetadataSource实例来处理,该实例只会查询其代表,直到它从其中一个实体获得具体答案。因此,如果您为方法定义了@Secured@PreAuthorize,则只会使用一个。

您应该只在您的应用中定义一个<global-method-security>元素。如果要将方法安全性应用于Web控制器或其中定义的其他Bean,则只需将其置于-servlet.xml上下文文件中。