Можно весной использовать безопасности @предварительного блокирования средств на весенне методы контроллеров?
может Весна безопасности использовать @PreAuthorize
на методах регуляторов весны?
7 ответов:
Да, он отлично работает.
вам нужно
<security:global-method-security pre-post-annotations="enabled" />
на...-servlet.xml
. Это также требует CGLIB прокси, поэтому либо ваши контроллеры не должны иметь интерфейсов, либо вы должны использоватьproxy-target-class = true
.
посмотреть Spring Security FAQ (выделено мной).
в веб-приложении Spring контекст приложения, который содержит Весенние бобы MVC для сервлета диспетчера часто отделяются от основной контекст приложения. Он часто определяется в файле приложение-сервлет.xml, где "myapp" - это имя, присвоенное весне DispatcherServlet в web.XML. Приложение может иметь несколько DispatcherServlets, каждый со своим собственным изолированным приложением контекст. Бобы в этих" дочерних " контекстах не видны остальным приложение. Контекст "родительского" приложения загружается с помощью ContextLoaderListener вы определяете в вашем интернете.xml и виден всем дочерние контексты. Этот родительский контекст обычно находится там, где вы определяете ваша конфигурация безопасности, включая элемент.) В результате любые ограничения безопасности, применяемые к методам в эти веб-бобы не будут применены, так как бобы не могут быть замечены от DispatcherServlet контексте. Вам нужно либо переместить объявление в веб-контекст или перемещение бобы, которые вы хотите защитить в главном контексте приложения.
как правило, мы рекомендуем применять метод безопасности на службу слой, а не на отдельных веб-контроллерах.
Если вы применяете pointcuts к слою сервиса, вам нужно только установить
<global-method-security>
в контексте вашего приложения.
Если вы используете Spring 3.1, вы можете сделать некоторые довольно интересные вещи с этим. Взгляните на https://github.com/mohchi/spring-security-request-mapping. это пример проекта, который интегрирует @PreAuthorize с Requestmappinghandlermapping Spring MVC, так что вы можете сделать что-то вроде:
@RequestMapping("/") @PreAuthorize("isAuthenticated()") public String authenticatedHomePage() { return "authenticatedHomePage"; } @RequestMapping("/") public String homePage() { return "homePage"; }
запрос на " / " вызовет authenticatedHomePage (), если пользователь аутентифицирован. В противном случае он вызовет homePage().
прошло более двух лет с тех пор, как этот вопрос был задан, но из-за проблем, которые у меня были сегодня, я бы предпочел отказаться от использования
@Secured
,@PreAuthorize
и т. д. на@Controller
s.то, что не сработало для меня было
@Validated
в сочетании с :@Controller @Secured("ROLE_ADMIN") public class AdministrationController { // @InitBinder here... @RequestMapping(value = "/administration/add-product", method = RequestMethod.POST) public String addProductPost(@ModelAttribute("product") @Validated ProductDto product, BindingResult bindingResult) { // ... }
валидатор просто не срабатывает (Spring MVC 4.1.2, Spring Security 3.2.5) и никакие проверки не выполняются.
подобные проблемы вызваны прокси CGLIB, используемыми Spring (когда нет интерфейса реализованный классом, Spring создает прокси CGLIB; если класс реализует какой - либо интерфейс, то генерируется Прокси JDK -документация,хорошо объяснил здесь и здесь).
как упоминалось в ответах, которые я связал выше, не лучше использовать аннотации безопасности Spring на уровне сервиса, который обычно реализует интерфейсы (поэтому используются Прокси JDK), поскольку это не приводит к таким проблемам.
если вы хотите защитить веб контроллеры, лучше использовать
<http>
и<intercept-url />
которые привязаны к определенным URL-адресам, а не к методам в контроллерах и работают довольно хорошо. В моем случае:<http use-expressions="true" disable-url-rewriting="true"> ... <intercept-url pattern="/administration/**" access="hasRole('ROLE_ADMIN')" /> </http>
уже есть ответ о том, как заставить его работать, изменив конфигурацию xml; однако, если вы работаете с конфигурацией на основе кода, Вы можете добиться того же, поместив следующую аннотацию поверх
@Configuration
класс:@EnableGlobalMethodSecurity(prePostEnabled=true)
чтобы расширить ответ, предоставленный Энди, вы можете использовать:
@PreAuthorize("hasRole('foo')")
для проверки конкретной роли.
сначала вам нужно добавить эту аннотацию в свой WebSecurityConfig, чтобы включить аннотации @Pre и @Post.
@EnableGlobalMethodSecurity(prePostEnabled = true)
вы также можете проверить роли / полномочия следующим образом
@PreAuthorize("hasAuthority('ROLE_ADMIN')")
эквивалентно
@PreAuthorize("hasRole('ROLE_ADMIN')")
вы также можете проверить несколько ролей / полномочий следующим образом
@PreAuthorize("hasAuthority('ROLE_ADMIN') or hasAuthority('ROLE_USER') or ...")