I am facing an issue in using the @PreAuthorize
annotation. Even if my user does not own the asked roles, my secured methods are executed.
My controller
My collegues found the trick.
The @EnableGlobalMethodSecurity(prePostEnabled = true) annotation must not be in the spring-security
configuration class but in the Servlet configuration class.
@Configuration
@EnableWebMvc
@EnableSpringDataWebSupport
@EnableJpaRepositories
@EnableGlobalMethodSecurity(prePostEnabled = true)
@ComponentScan(basePackages = { "mypackage.spring.rest" }, excludeFilters = @Filter(type = FilterType.ANNOTATION, value = Configuration.class))
public class SpringRestConfiguration {
}
And it works !
TLDR: @EnableAspectJAutoProxy(proxyTargetClass = true)
on WebConfig can be used instead.
The root of the problem may be that Spring doesn't generate controller's proxy classes - by default Spring wraps into proxies only those beans which are defined as interface and Spring IoC find their implementation. If your controllers are classes which don't implement/extend anything, CGLIB proxying has to be used (I recommend reading about Spring Proxying mechanisms), so proxy classes are generated and injected as controllers implementation - that's the place where Spring included an extra logic to respect @PreAuthorize
and @PostAuthorize
annotations conditions.
On Spring v5 (not Spring Boot), when @EnableGlobalMethodSecurity(prePostEnabled = true)
is used on SecurityConfiguration
only, it won't be picked up by WebConfig
. Moving it to WebConfig
will enable handling pre post annotations by Spring Security as well as it will switch on CGLIB proxy mechanism.
Personally, I recommend just adding @EnableAspectJAutoProxy(proxyTargetClass = true)
on WebConfig and leaving @EnableGlobalMethodSecurity
in SecurityConfig
.
I have tested it on Spring v5 only, but due to documentation it should work the same on Spring v4.