问题
Spring AOP runs everything through proxies which sadly can't be everywhere. For this reason Spring Security's annotations @PreAuthorize
, @PostAuthorize
, @PreFilter
and @PostFilter
(also @Secured
) will not be taken into consideration when calls are not going through said proxies. Proxies are created only for singletons (@Bean
s) so We are greatly limited when We want to secure methods on specific objects (such as JPA @Entities
) that are not beans. Proxies also won't be called within calling objects (bean calling its methods in context of self - this).
I know that Spring has suppot not only for Spring AOP but also real AOP - AspectJ. Not only that, but it SHOULD support AspectJ out of box. Testament to this is:
@EnableGlobalMethodSecurity(mode = AdviceMode.ASPECTJ, securedEnabled = true, prePostEnabled = true)
When enabled, Spring will require (crash on startup otherwise) aspectj dependency, which is provided within:
'org.springframework.security:spring-security-aspects'
After adding this dependency we will have AspectJ libraries in classpath and will get:
org.springframework.security.access.intercept.aspectj.aspect
with:
public aspect AnnotationSecurityAspect implements InitializingBean
But here it all ends. There is no documentation that I could find that would state how to further enable aspectj weaving. Setting @EnableGlobalMethodSecurity(mode = AdviceMode.ASPECTJ)
certainly DOES something as we lose standard Spring AOP - security annotations stop working anywhere (on Beans) and at the same time they are not weaved with AspectJ.
Does anyone have some knowledge on Spring's support for this out of box (compile-time weaving) and what further configuration is needed? Maybe I need to weave it myself? Do I need some specific libraries for building?
Version: Spring 5.2.1.RELEASE (all packages).
回答1:
@DimaSan comment helped me find few threads/issues I missed while doing my search and while many of them are too years-outdated I managed to setup my app.
Turns out I was actually very close and by making few updates and changing dependencies/plugins on gradle I have a working environment.
Gradle: 5.6.4
with:
plugins {
id "io.freefair.aspectj.post-compile-weaving" version "4.1.6"
}
dependencies {
aspect 'org.springframework.security:spring-security-aspects'
runtime 'org.springframework.security:spring-security-aspects'
}
Spring setup at 5.2.1.RELEASE
with
spring-boot-starter-
web
data-jpa
security
With above setup this is actually only thing needed:
@EnableGlobalMethodSecurity(mode = AdviceMode.ASPECTJ, securedEnabled = true, prePostEnabled = true)
Finally if You are not using Gradle (e.g. want to use STS/Eclipse Run Configuration), you will add:
-javaagent:C:\Users\USER\.gradle\caches\modules-2\files-2.1\org.aspectj\aspectjweaver\1.9.4\<cache-string>\aspectjweaver-1.9.4.jar
.gradle
and 1.9.4
being case for my current setup/version.
Note that this is yet untested (but working with JPA/Hibernate) with e.g. Transaction management and I will comment on it once I start using complex transactions where weaving would create issues.
来源:https://stackoverflow.com/questions/59204819/enabling-compile-time-aspecj-for-spring-method-security