Можно весной использовать безопасности @предварительного блокирования средств на весенне методы контроллеров?


может Весна безопасности использовать @PreAuthorize на методах регуляторов весны?

7 67

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 ...")