javaspring-bootgradleldapspring-ldap

LdapCtxFactory because module java.naming does not export com.sun.jndi.ldap to unnamed module


WebSecurityConfigurerAdapter:

@Component
@EnableWebSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter
{
   @Override
   protected void configure(HttpSecurity httpSecurity) throws Exception
   {
      httpSecurity
               .authorizeRequests()
               .antMatchers("/abc/**").permitAll()
               .anyRequest()
               .authenticated()
               .and()
               .csrf()
               .disable()
               .httpBasic();
   }

   @Override
   public void configure(AuthenticationManagerBuilder auth) throws Exception
   {
      auth.ldapAuthentication()
          .userDnPatterns("uid={0},ou=people")
          .userSearchBase("ou=people")
          .userSearchFilter("uid={0}")
          .groupSearchBase("ou=groups")
          .groupSearchFilter("uniqueMember={0}")
          .contextSource()
          .url("ldap://localhost:8389/dc=concretepage,dc=com")
          .and()
          .passwordCompare()
          .passwordEncoder(passwordEncoder())
          .passwordAttribute("userPassword");
   }

   @Bean
   public PasswordEncoder passwordEncoder() {
      BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
      return passwordEncoder;
   }

Spring-Version: SPRING_BOOT_VERSION = "2.6.6"

plugins {
    id 'java-library'
}

dependencies {
    implementation "org.springframework.boot:spring-boot:${SPRING_BOOT_VERSION}"
    implementation "org.springframework.boot:spring-boot-starter-web:${SPRING_BOOT_VERSION}"
    implementation "org.springframework.boot:spring-boot-starter-thymeleaf:${SPRING_BOOT_VERSION}"

    api "javax.servlet:javax.servlet-api:${JAVAX_SERVLET_VERSION}"

    compileOnly 'io.crnk:crnk-gen-java' 
    annotationProcessor 'io.crnk:crnk-gen-java'

    gradle.beforeProject { Project project ->
        project.with {
            apply plugin: 'io.spring.dependency-management'
            dependencyManagement {
                imports {
                    mavenBom "io.crnk:crnk-bom:${CRNK_VERSION}"
                }
            }
        }
    }


    implementation platform("io.crnk:crnk-bom:${CRNK_VERSION}")
    annotationProcessor platform("io.crnk:crnk-bom:${CRNK_VERSION}")

    implementation "io.crnk:crnk-setup-spring-boot2"
    implementation "io.crnk:crnk-home"

    implementation "io.crnk:crnk-security"
    implementation 'org.springframework.boot:spring-boot-starter-security:2.7.2'
    implementation 'org.springframework.ldap:spring-ldap-core'
    implementation 'org.springframework.security:spring-security-ldap:5.4.3'
    implementation 'com.unboundid:unboundid-ldapsdk:4.0.14'

    testImplementation("org.springframework.boot:spring-boot-starter-test:${SPRING_BOOT_VERSION}")
}

gradle.properties:

systemProp.http.ssl.insecure=true
systemProp.http.ssl.allowall=true
systemProp.http.ssl.ignore.validity.dates=true

org.gradle.jvmargs=-Djavax.net.ssl.trustStore="./cacerts" -Djavax.net.ssl.trustStorePassword=changeit \
  --add-exports java.naming/com.sun.jndi.ldap=spring.ldap.core

./gradlew --version

------------------------------------------------------------
Gradle 7.4.2
------------------------------------------------------------

Build time:   2022-03-31 15:25:29 UTC
Revision:     540473b8118064efcc264694cbcaa4b677f61041

Kotlin:       1.5.31
Groovy:       3.0.9
Ant:          Apache Ant(TM) version 1.10.11 compiled on July 10 2021
JVM:          17.0.2 (Oracle Corporation 17.0.2+8-86)
OS:           Windows 10 10.0 amd64

The error:

Error starting ApplicationContext. To display the conditions report re-run your application with 'debug' enabled.
2022.08.02 07:16:32.051 [main] ERROR o.s.boot.SpringApplication:830 - Application run failed
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'springSecurityFilterChain' defined in class path resource [org/springframework/security/config/annotation/web/configuration/WebSecurityConfiguration.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [javax.servlet.Filter]: Factory method 'springSecurityFilterChain' threw exception; nested exception is java.lang.IllegalAccessError: class org.springframework.ldap.core.support.AbstractContextSource (in unnamed module @0x1d296da) cannot access class com.sun.jndi.ldap.LdapCtxFactory (in module java.naming) because module java.naming does not export com.sun.jndi.ldap to unnamed module @0x1d296da
    at org.springframework.beans.factory.support.ConstructorResolver.instantiate(ConstructorResolver.java:658)
    at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:486)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1352)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1195)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:582)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:542)
    at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:335)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:333)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:208)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:322)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:208)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:953)
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:918)
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:583)
    at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:145)
    at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:740)
    at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:415)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:303)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1312)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1301)

Solution

  • Try adding --add-exports java.naming/com.sun.jndi.ldap=ALL-UNNAMED instead of --add-exports java.naming/com.sun.jndi.ldap=spring.ldap.core to your JVM arguments.

    But a better solution would be to align all the dependency versions with the Spring Boot version you use (2.6.6):