Spring Security + JSR 250 + EJB 3.1 не работает

В моем веб-приложении JEE6 (в основном CDI, EJB 3.1 и JSF 2) используется Spring Security 3, но не внедрение Spring Spring или MVC. Я реализовал Spring AuthenticationProvider для обработки входа в систему. Во время входа в систему я добавляю роли своим пользователям в зависимости от определенной бизнес-логики.

Теперь я хочу использовать аннотации JSR 250 для защиты моей бизнес-логики. Моя бизнес-логика реализована с использованием EJB без сохранения состояния (версия 3.1).

Я включил XML-файл контекста Spring в файл web.xml следующим образом:

<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>
        /WEB-INF/spring/applicationContext-security.xml
    </param-value>
</context-param>

А вот содержимое файла XML:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
   xmlns:security="http://www.springframework.org/schema/security"
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xsi:schemaLocation="http://www.springframework.org/schema/beans
      http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
      http://www.springframework.org/schema/security
      http://www.springframework.org/schema/security/spring-security-3.1.xsd">


<security:global-method-security jsr250-annotations="enabled"/>

<security:http auto-config="false">
    <security:intercept-url pattern="/pages/**" access="ROLE_USER"/>
    <security:intercept-url pattern="/**" access="IS_AUTHENTICATED_ANONYMOUSLY"/>
    <security:form-login login-page="/login.jsf"/>
    <security:anonymous/>
    <security:custom-filter ref="logoutFilter" position="LOGOUT_FILTER"/>
</security:http>

<bean id="logoutFilter" class="org.springframework.security.web.authentication.logout.LogoutFilter">
    <constructor-arg index="0" value="/login.jsf"/>
    <constructor-arg index="1">
        <list>
            <bean id="customLogoutHandler" class="com.example.client.security.CustomLogoutHandler"/>
            <bean id="securityContextLogoutHandler" class="org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler"/>
        </list>
    </constructor-arg>
    <property name="filterProcessesUrl" value="/logout.jsf"/>
</bean>

<security:authentication-manager>
    <security:authentication-provider ref="customAuthenticationProvider"/>
</security:authentication-manager>

<bean id="customAuthenticationProvider"
      class="com.example.client.security.CustomAuthenticationProvider"/>
</beans>

В моих классах я использую аннотации классов (уровень типа), чтобы сказать, что все методы должны быть доступны только пользователям с определенной ролью:

@Model
@RolesAllowed("ROLE_GROUP")
public class UserListAction {

Однако также пользователи с только ролью ROLE_USER имеют доступ к любой функции этого класса. Я проверил, что пользователи не имеют неправильные роли при отладке с помощью следующего кода:

    Collection<? extends GrantedAuthority> authorities = SecurityContextHolder.getContext().getAuthentication().getAuthorities();

Как и ожидалось, коллекция прав доступа не содержит прав доступа ROLE_GROUP.

Кажется, мои аннотации полностью игнорируются, но почему? Я также пробовал аннотации Spring до публикации, но они, похоже, не имеют никакого эффекта.

1 ответ

Решение

По умолчанию Spring Security использует стандартную Spring AOP, которая ограничена bean-компонентами, которые создаются контекстом приложения Spring. Объекты (такие как EJB), жизненный цикл которых не контролируется Spring, не будут затронуты. Аналогично, если вы создаете экземпляр объекта, используя new или какая-то другая структура создает объект по требованию.

Единственный вариант, который вам нужно применить, - перехватчик метода безопасности для всех экземпляров объекта - использовать Aspectj. Ответы на этот вопрос, вероятно, хорошее место для начала.

Другие вопросы по тегам