2012-01-30 102 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上下文文件中。