Защита метода контроллера с помощью @RolesAllowed и @PreAuthorize
Я уже некоторое время бьюсь о эту голову. Я сделал все возможное, чтобы найти подходящее решение, и следовал многим примерам и решениям Stackru.
Во-первых, я использую решение на основе аннотаций. Когда я аннотирую свои сервисы, prePostEnabled работает, но не когда я аннотирую контроллеры, это не так. Кроме того, даже на моих сервисах jsr250Enabled не работает.
Я обнаружил, что многие дела закрыты путем перемещения аннотации из конфигурации безопасности в конфигурацию MVC, которая в моем случае не работает.
У меня есть настройка, которая выглядит следующим образом: https://github.com/spring-projects/spring-security-oauth-javaconfig/tree/master/samples/oauth2-sparklr
Но я использую Servlet 3.0, и в моем web.xml ничего нет.
Мой SecurityInitializer выглядит так:
public class SecurityWebApplicationInitializer extends AbstractSecurityWebApplicationInitializer {
}
Мой инициализатор MVC выглядит так:
public class MvcWebApplicationInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
@Override
protected Class<?>[] getRootConfigClasses() {
return new Class<?>[]{WebSecurityConfig.class, MethodSecurityConfig.class};
}
@Override
protected Class<?>[] getServletConfigClasses() {
return new Class<?>[]{SpringMvcConfig.class};
}
@Override
protected String[] getServletMappings() {
return new String[]{ApiPaths.API + "/*", "/res.jsp"};
}
Моя конфигурация WebSecurity инициализируется следующим образом:
@Configuration
@EnableWebSecurity
@ComponentScan(value = {"com.roler.res.**.server"}, excludeFilters = {
@Filter(type = FilterType.ASSIGNABLE_TYPE, value = SpringMvcConfig.class),
@Filter(type = FilterType.ASSIGNABLE_TYPE, value = MethodSecurityConfig.class),
@Filter(type = FilterType.REGEX, pattern = "com.xyz.*.controller.*")})
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
И мой SpringMvcConfig инициализируется так:
@Configuration
@EnableWebMvc
@ComponentScan(value = "com.xyz.**.controller")
public class SpringMvcConfig extends WebMvcConfigurerAdapter {
Если у вас есть какие-либо идеи, я не в духе, спасибо!
2 ответа
Симптомы, которые вы описываете, заставляют меня задуматься над проблемой проксирования. Аннотации отлично работают на сервисном уровне, потому что сервисы обычно реализуют интерфейсы, и Spring может легко использовать JDK-прокси для установки авторизации AOP.
Но контроллеры обычно не реализуют интерфейсы. Вот почему аннотации PreAuthorize чаще используются в сервисном слое. ИМХО, вам лучше попробовать использовать авторизацию на основе шаблонов URL вместо аннотаций PreAuthorize на контроллере. Альтернативой может быть использование прокси целевого класса с помощью CGLIB.
Использовать PreAuthorize
и аннотации JSR-250, вы должны
Добавьте в свой весенний класс конфигурации безопасности:
@EnableGlobalMethodSecurity(prePostEnabled = true, jsr250Enabled = true)
если вы используете в своем приложении Spring AOP Spring с прокси-серверами JDK, создайте все классы контроллеров, в которых вы хотите использовать безопасность методов, реализуйте интерфейсы, объявляющие все защищенные методы
если вы используете в своем приложении Spring AOP с прокси-серверами CGLIB, добавьте
proxyTargetClass = true
в@EnableGlobalMethodSecurity
:@EnableGlobalMethodSecurity(prePostEnabled = true, jsr250Enabled = true, proxyTargetClass = true)
если вы хотите использовать прокси-серверы CGLIB с версией Spring под 3.2, добавьте библиотеку CGLIB в ваш путь к классам (классы CGLIB включены в Spring 3.2+)
- избегайте смешивания прокси-серверов CGLIB и JDK, так как это не рекомендуется в документации Spring: во время выполнения несколько секций объединяются в одного создателя унифицированного авто-прокси, который применяет самые сильные настройки прокси, какие-либо из секций (обычно из разных файлов определений XML-бинов) указано. Это также относится к элементам и. Для ясности: использование 'proxy-target-class="true"' включено, или элементы заставят использовать прокси CGLIB для всех трех из них.
Но в любом случае мой совет - попытаться переместить метод защиты на уровень обслуживания, который обычно уже поддерживает AOP.
Я заметил две вещи (как упомянуто в этой теме):
- prePostEnabled в аннотации для включения аннотаций Pre/Post
- использование прокси CGLib (Серж тоже об этом упомянул)
Есть ли у этих @EnableGlobalMethodSecurity эти два атрибута?
@EnableGlobalMethodSecurity(prePostEnabled = true, proxyTargetClass = true)