LdapCtxFactory,因为模块 java.naming 不会将 com.sun.jndi.ldap 导出到未命名模块

问题描述 投票:0回答:4

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_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.属性:

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

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

错误:

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)
java spring-boot gradle ldap spring-ldap
4个回答
8
投票

尝试在 JVM 参数中添加

--add-exports java.naming/com.sun.jndi.ldap=ALL-UNNAMED
而不是
--add-exports java.naming/com.sun.jndi.ldap=spring.ldap.core

但是更好的解决方案是将所有依赖项版本与您使用的 Spring Boot 版本(2.6.6)保持一致:

  • 对于
    org.springframework.boot:spring-boot-starter-security
    删除版本或设置
    2.6.6
  • org.springframework.security:spring-security-ldap:5.4.3
    太旧了,至少应该是版本5.6.2。有了这个,您可能根本不需要任何明确的
    --add-exports
  • 删除
    org.springframework.ldap:spring-ldap-core
    -
    org.springframework.security:spring-security-ldap
    自动将其引入。

3
投票

对我来说,添加:

--add-opens=java.naming/com.sun.jndi.ldap=ALL-UNNAMED

而不是--add-exports


1
投票

此解决方案可能适用于那些不想明确使用

--add-exports
的人。
就我而言,升级并使用正确的 ldap core jar 后问题得到解决。之前它使用的是 2.2.0.RELEASE 版本。

<dependency>
    <groupId>org.springframework.ldap</groupId>
    <artifactId>spring-ldap-core</artifactId>
    <!-- version>2.2.0.RELEASE</version -->
    <version>3.0.2</version>
</dependency>

0
投票

就我而言,我在编译时使用类

com.sun.jndi.ldap.LdapCtxFactory
,因此将
--add-exports=java.naming/com.sun.jndi.ldap=ALL-UNNAMED
添加到
org.gradle.jvmargs
没有帮助。我需要将它作为编译器参数传递。像下面这样:

compileJava {
    options.compilerArgs += [
        '--add-exports=java.naming/com.sun.jndi.ldap=ALL-UNNAMED'
    ]
}
© www.soinside.com 2019 - 2024. All rights reserved.