防止 SpringSecurity 创建基于 cglib 的代理

Prevent SpringSecurity from creating cglib based proxy

我正在使用 spring-boot 2.3.9 和 spring-security with keycloak 12.0.4。

@Configuration
@KeycloakConfiguration
@ConditionalOnProperty("keycloak.enabled")
@Import(KeycloakSpringBootConfigResolver.class)
@EnableWebSecurity
@EnableGlobalMethodSecurity(securedEnabled = true, proxyTargetClass = false) // If I exclude this, no cglib based proxy is created, but @Secured is not applied either
public class SecurityConfig extends KeycloakWebSecurityConfigurerAdapter {

还有我的服务 bean 创建配置

@Configuration(proxyBeanMethods = false)
public class EnvironmentConfig {

    @Bean
    // @Scope(proxyMode = ScopedProxyMode.INTERFACES) // Has no effect
    MyServiceInterfaceSecured myService() { new ImplA/ImplB/ImplC() }

}

出于某种原因 spring 创建了基于 cglib 的代理,这会导致其他问题(最终方法...)

09:56:38.828 DEBUG [,] --- [main] m.DelegatingMethodSecurityMetadataSource : Caching method [CacheKey[example.MyServiceImplA; ...] with attributes [...]
09:57:12.992  INFO [,] --- [main] o.s.a.f.CglibAopProxy                    : Unable to proxy interface-implementing method [public final java.util.List example.MyServiceImplA.sync()] because it is marked as final: Consider using interface-based JDK proxies instead!
09:57:12.992 DEBUG [,] --- [main] o.s.a.f.CglibAopProxy                    : Final method [public final java.util.List example.MyServiceImplA.sync()] cannot get proxied via CGLIB: Calls to this method will NOT be routed to the target instance and might lead to NPEs against uninitialized fields in the proxy instance.

TLDR: 我如何告诉 spring 为我的 bean 创建一个基于接口的代理而不是基于 cglib 的代理?

(或者我可以检查哪个 bean/code/log 来分析它尝试使用 cglib 代理的原因)

编辑: 这可能与 spring-cloud-starter-sleuth 有关。如果我删除该依赖项,一切都会按预期进行。但我也需要侦探。

我通过从 spring-cloud-starter-sleuth 中排除 spring-boot-starter-aop 来修复它。

    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-sleuth</artifactId>
        <exclusions>
            <exclusion>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-aop</artifactId>
            </exclusion>
        </exclusions>
    </dependency>

编辑: 我打开了一个问题,要求依赖项是可选的或解释为什么需要它:

https://github.com/spring-cloud/spring-cloud-sleuth/issues/1933