2
votes

I'm using spring-boot 2.3.9 and 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 {

And my service bean creation config

@Configuration(proxyBeanMethods = false)
public class EnvironmentConfig {

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

}

For some reason spring creates cglib based proxies, which causes other issues (final methods...)

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: How do I tell spring to create an interface based proxy for my beans instead of cglib based proxies?

(or which bean/code/log can I check to analyze why it tries to use the cglib proxy)

EDIT: This might be related to spring-cloud-starter-sleuth. If I remove that dependency, everything works as expected. But I also need sleuth.

1

1 Answers

0
votes

I fixed it by excluding spring-boot-starter-aop from spring-cloud-starter-sleuth.

    <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>

EDIT: I opened an issue asking for the dependency to be optional or an explanation why it is required:

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