3

Maven と Eclipse Juno を使用して、Tomcat 7 のカスタム領域を開発しています。

これは、 Implement a Tomcat Realm with LDAP authentication and JDBC authorizationで説明されているソリューションによく似ています。

  • インターフェースがわずかに変更されたため、適応された hasRole メソッド (最初のパラメーターとしての追加のラッパー) ;
  • いくつかの社内固有のもの。

このレルムをEclipseでデバッグしようとすると、次の例外が発生し続けます:

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

私が見る限り、このクラスは $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

このプロジェクトは非常に単純で、maven で構築された jar が次のように構成されています。

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

結果の jar は $TOMCAT_ROOT/lib に配置されます。

何か案が ?

補足 : この問題は LDAP 接続でのみ発生します。非 SSL LDAP 接続では、すべて問題ありません。

次のようなコードを使用して、オーバーロードされた「オープン」メソッドのパラメーターを手動で設定した場合でも、次のようになります。

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

}

... InitialDirContext コンストラクターで奇妙な例外が発生します。

更新: javax.net.ssl.trustStore プロパティを、jar に含まれるファイルではなくローカル ファイルに設定すると、機能します。

そう :

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

動作します。理由はありますか?

4

1 に答える 1

1

わかりました。バグは、sun ldap ライブラリが jar ファイルから jks ファイルを読み込めないことでした。回避策は、ファイルを車から tomcat temp dir に抽出し、この「実際の」ファイルを javax.net.ssl.trustStore プロパティとして設定することでした。

        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);
于 2012-11-13T12:52:09.380 に答える