Question

I am developping a custom realm for Tomcat 7 using maven and eclipse juno.

It looks a lot like the solution described in Implement a Tomcat Realm with LDAP authentication and JDBC authorization , with :

  • an adapted hasRole method, as the interface slightly changed (additional Wrapper as first parameter ) ;
  • some in-house specific stuff.

When I try to debug this realm with eclipse, I keep bumping on the following exception :

The type org.apache.tomcat.util.buf.ByteChunk cannot be resolved. It is indirectly referenced from required .class files

As far as I can see, this class is in $TOMCAT_ROOT/lib/tomcat-coyote.jar :

unzip -t /opt/apache-tomcat-7.0.32/lib/tomcat-coyote.jar | grep ByteChunk
    testing: org/apache/tomcat/util/buf/ByteChunk$ByteInputChannel.class   OK
    testing: org/apache/tomcat/util/buf/ByteChunk$ByteOutputChannel.class   OK
    testing: org/apache/tomcat/util/buf/ByteChunk.class   OK

The project is quite simple, a maven-built jar configured this way :

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <artifactId>senrealm</artifactId>
    <groupId>fr.senat</groupId>
    <packaging>jar</packaging>
    <version>0.1.0</version>
    <name>Realm d'authentification</name>
    <url></url>

    <properties>
        <maven.compiler.source>1.6</maven.compiler.source>
        <maven.compiler.target>1.6</maven.compiler.target>
        <tomcat.version>7.0.32</tomcat.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.apache.tomcat</groupId>
            <artifactId>tomcat-catalina</artifactId>
            <version>${tomcat.version}</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>org.apache.tomcat</groupId>
            <artifactId>tomcat-coyote</artifactId>
            <version>${tomcat.version}</version>
        </dependency>
    </dependencies>
    <build>
        <resources>
              <resource>
                      <directory>src/main/resources</directory>
                      <filtering>true</filtering>
                      <excludes>
                              <exclude>ldap.jks</exclude>
                      </excludes>
              </resource>
              <resource>
                      <directory>src/main/resources</directory>
                      <filtering>false</filtering>
                      <includes>
                              <include>ldap.jks</include>
                      </includes>
              </resource>
      </resources>
   </build>
</project>

The resulting jar is placed in $TOMCAT_ROOT/lib.

Any idea ?

Complement : the problem occurs only with a ldaps connection. With a non SSL ldap connection, everything is alright.

Even when I manually set parameters in m an overloaded "open" method, with code such as :

@Override
protected DirContext open() throws NamingException {

    URL ts = getClass().getResource("/ldap.jks");
    System.setProperty("javax.net.ssl.trustStore", ts.getFile());

    Properties ldapProperties;
    ldapProperties = new Properties();
ldapProperties.put(javax.naming.Context.INITIAL_CONTEXT_FACTORY,"com.sun.jndi.ldap.LdapCtxFactory");
    ldapProperties.put(javax.naming.Context.PROVIDER_URL, "ldaps://ldap.senat.fr:636/dc=senat,dc=fr");
    ldapProperties.put("com.sun.jndi.ldap.connect.pool","true");

    ldapProperties.put(javax.naming.Context.SECURITY_AUTHENTICATION, "simple");
    ldapProperties.put(javax.naming.Context.SECURITY_PROTOCOL, "ssl");
    ldapProperties.put(javax.naming.Context.SECURITY_PRINCIPAL, "uid=batchges, ou=comptes, dc=senat, dc=fr");
    ldapProperties.put(javax.naming.Context.SECURITY_CREDENTIALS, "xxxxx");

    DirContext newDirContext = new InitialDirContext(ldapProperties);
    return newDirContext;

}

... the strange exception occurs in InitialDirContext constructor.

UPDATE : if I set the javax.net.ssl.trustStore property to a local file rather than a file included in the jar, it works.

So :

@Override
protected DirContext open() throws NamingException {
    System.setProperty("javax.net.ssl.trustStore", "/tmp/ldap.jks");
    return super.open();
}

works. Any idea why ?

Était-ce utile?

La solution

ok, so, the bug was that the sun ldap library can not load the jks file from the jar. The workaround was to extract the file from the car to tomcat temp dir, then setting this "real" file as javax.net.ssl.trustStore property.

        String tmpdir = System.getenv("CATALINA_TMPDIR");
        if(tmpdir == null)
            tmpdir = System.getenv("CATALINA_HOME") + "/temp";
        final String tmpJKSfile = tmpdir + "/ldap.jks";
        URL ts = getClass().getResource("/ldap.jks");
        try {
            InputStream in = new BufferedInputStream(ts.openStream());
            OutputStream out = new BufferedOutputStream(new FileOutputStream(tmpJKSfile));
            IOUtils.copy(in, out);
            out.flush();
            out.close();
            in.close();
        } catch (IOException eio) {
            /* your logging */
        }


        System.setProperty(TrustStoreProperty, tmpJKSfile);
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top