markus
markus

Reputation: 83

spring kafka ssl classpath truststore

How can I use with spring kafka(without sboot) for SSL configuration a relative/classpath path for specifying location of truststore for example?

It works only when absolute path is provided.

Suprisingly it works with relative path(within jar) when runnig with spring boot..

Upvotes: 2

Views: 7363

Answers (2)

midnight
midnight

Reputation: 132

My patch for this was to copy the key-store over to the filesystem while spring boots up. (rather have your own ConsumerFactory than the one from KafkaAutoConfiguration)

  1. take the name of the key-store from your properties (so the key-store can be named different in your stages DEV/INT/PROD)
  2. copy it the filesystem of your k8n pod (use different target than '/tmp', if your run locally on Windows)
  3. update the KafkaProperties with the new location in the file system.

    @Configuration
    @RequiredArgsConstructor
    public class KafkaConfig {
    
        private final KafkaProperties kafkaProps;
    
        @Bean
        @ConditionalOnProperty(value = "spring.kafka.enabled", havingValue = "true")
        public ConsumerFactory<?, ?> consumerFactory() throws IOException {
            Path fileSystemKeyStorePath = Paths.get("/tmp", "keystore.pfx");
    
            Resource keyStoreLocationFromProperties = kafkaProps.getSsl().getKeyStoreLocation();
            Files.copy(keyStoreLocationFromProperties.getInputStream(),
                fileSystemKeyStorePath, StandardCopyOption.REPLACE_EXISTING);
    
            Ssl ssl = kafkaProps.getSsl();
            ssl.setKeyStoreLocation(new FileSystemResource(fileSystemKeyStorePath));
    
            return new DefaultKafkaConsumerFactory(kafkaProps.buildConsumerProperties());
        }
    }

Upvotes: 0

Gary Russell
Gary Russell

Reputation: 174514

The file is read by Kafka, not Spring.

Kafka has no knowledge of Spring's classpath resource abstraction.

I think you are mistaken about boot; it only works there if the jar is exploded; boot has this code in KafkaProperties...

    map.from(this::getTrustStoreLocation).as(this::resourceToPath)
            .to(properties.in(SslConfigs.SSL_TRUSTSTORE_LOCATION_CONFIG));

...

private String resourceToPath(Resource resource) {
    try {
        return resource.getFile().getAbsolutePath();
    }
    catch (IOException ex) {
        throw new IllegalStateException(
                "Resource '" + resource + "' must be on a file system", ex);
    }
}

To use a truststore from within a jar, you would need to first copy it to a filesystem (e.g. /tmp) before starting the application context.

Upvotes: 1

Related Questions