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. Ответы на этот вопрос, вероятно, хорошее место для начала.