@ Защищенные аннотации работают, но @PostAuthorize с PermissionEvaluator не работает - PullRequest
3 голосов
/ 30 января 2012

Следующая проблема сводит меня с ума:

У меня есть следующие настройки:

  • интерфейс StudyService
  • @ Service StudyServiceImpl реализует StudyService
  • @ Controller StudyServiceController реализует StudyService
  • SampleDAOImpl реализует SampleDAO
  • Права доступа CdmPermissionEvaluator

У меня следующий код:

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

@Secured работает, так как я должен войти в систему, когда он присутствует.Однако @PostAutorize не работает, даже когда я закомментирую @Secured.У меня есть запись журнала в CdmPermissionEvaluator.hasPermission (), и он никогда не регистрируется.Это также тот случай, когда я закомментирую аннотацию @Secured (чтобы избежать того, что @PostAuthorize не будет оценен из-за избирателя AffirrativeBased по умолчанию).

Соответствующие части 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>
...

Соответствующие части spring-servlet.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>
...

Соответствующие части applicationContext.xml:

<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>

Есть идеи, что я здесь не так делаю?

До того, как я выполнил эту настройку, у меня были аннотации @PostAuthorize с выражениями Spring EL (без разрешенияEvaluator) в @Service StudyServiceImpl, и это сработало.Так что я делаю не так, и в чем разница с предыдущей настройкой?

Заранее спасибо,

Арно

1 Ответ

2 голосов
/ 01 февраля 2012

Это не сработает, потому что вы не можете смешивать разные типы аннотаций в одном методе без получения странных результатов.Поэтому рекомендуется придерживаться единой опции «метаданные безопасности» для каждого класса или интерфейса, который вы хотите защитить.

Более подробно, несколько различных источников метаданных (защищенные аннотации, пре-пост-аннотации, определения pointcut,Аннотации JSR-250) могут использоваться в приложении.Все они обычно обрабатываются экземпляром DelegatingMethodSecurityMetadataSource, который будет запрашивать только своих делегатов, пока не получит конкретный ответ от одного из них.Поэтому, если для метода определены @Secured и @PreAuthorize, будет использоваться только один.

В вашем приложении должен быть определен только один элемент <global-method-security>.Вам нужно только поместить его в контекстный файл -servlet.xml, если вы применяете метод защиты к веб-контроллерам или другим компонентам, определенным там.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...