Search code examples
javaspring-bootspring-securityapache-kafkajaas

Kafka authentication with Jaas config


I have set up my Kafka jaas config as an external bean in my spring boot application to read my configuration from my application.yaml file.

But I am facing an error reading my jaas keytab file from my yaml file.

Error faced

Caused by: javax.security.auth.login.LoginException: Could not login: the client is being asked for a password, but the Kafka client code does not currently support obtaining a password from the user. not available to garner  authentication information from the user
at jdk.security.auth/com.sun.security.auth.module.Krb5LoginModule.promptForPass(Krb5LoginModule.java:918) ~[jdk.security.auth:na]
at jdk.security.auth/com.sun.security.auth.module.Krb5LoginModule.attemptAuthentication(Krb5LoginModule.java:738) ~[jdk.security.auth:na]
at jdk.security.auth/com.sun.security.auth.module.Krb5LoginModule.login(Krb5LoginModule.java:592) ~[jdk.security.auth:na]
at java.base/javax.security.auth.login.LoginContext.invoke(LoginContext.java:726) ~[na:na]
at java.base/javax.security.auth.login.LoginContext$4.run(LoginContext.java:665) ~[na:na]
at java.base/javax.security.auth.login.LoginContext$4.run(LoginContext.java:663) ~[na:na]
at java.base/java.security.AccessController.doPrivileged(AccessController.java:691) ~[na:na]
at java.base/javax.security.auth.login.LoginContext.invokePriv(LoginContext.java:663) ~[na:na]
at java.base/javax.security.auth.login.LoginContext.login(LoginContext.java:574) ~[na:na]
at org.apache.kafka.common.security.authenticator.AbstractLogin.login(AbstractLogin.java:60) ~[kafka-clients-2.5.1.jar:na]
at org.apache.kafka.common.security.kerberos.KerberosLogin.login(KerberosLogin.java:103) ~[kafka-clients-2.5.1.jar:na]
at org.apache.kafka.common.security.authenticator.LoginManager.<init>(LoginManager.java:62) ~[kafka-clients-2.5.1.jar:na]
at org.apache.kafka.common.security.authenticator.LoginManager.acquireLoginManager(LoginManager.java:112) ~[kafka-clients-2.5.1.jar:na]
at org.apache.kafka.common.network.SaslChannelBuilder.configure(SaslChannelBuilder.java:158) ~[kafka-clients-2.5.1.jar:na]

This is how I have configured my jaas

KafkaJaasConfigurationProperty.java

@Component
@ConfigurationProperties(prefix = "kafka.jaas")
@Getter
@Setter
public class KafkaJaasConfigurationProperties {
  private Map<String, String> options;
}

application.yml

kafka:
 jaas:
  options:
   useKeyTab: true
   keytab: keytab-value
   storeKey: true
   debug: true
   serviceName: kafka
   principal: pricipal-value

KafkaJaasConfigurationBean.java

@Bean
public KafkaJaasLoginModuleInitializer jaasConfig(
    KafkaJaasConfigurationProperties kafkaJaasConfigurationProperties
) throws IOException {
    var jaasConfig = new KafkaJaasLoginModuleInitializer();
    jaasConfig.setControlFlag(KafkaJaasLoginModuleInitializer.ControlFlag.REQUIRED);
    jaasConfig.setOptions(kafkaJaasConfigurationProperties.getOptions());
    return jaasConfig;
}

Any help will be appreciated. Thanks!


Solution

  • Looking at the error it seems like the keytab file from the jass config you provided is not getting picked up by the KafkaJaasLoginModuleInitializer .

    I can see there is a typo in your jass configuration i.e "keytab" property value will be "keyTab"

    kafka:
     jaas:
      options:
       useKeyTab: true
       keyTab: keytab-value #Try changing this
       storeKey: true
       debug: true
       serviceName: kafka
       principal: pricipal-value
    

    I think this should work and it should be able to pick up keytab file.

    SPRING KAFKA EXAMPLE

    But if your are using spring kafka you can also directly give the jaas configuration without creating your own bean for KafkaJaasLoginModuleInitializer.

    Spring kafka example application.yaml

    spring:
      kafka:
        jaas:
          control-flag: required
          enabled: true
          login-module: com.sun.security.auth.module.Krb5LoginModule
          options:
            useKeyTab: true
            keyTab: keytab-value
            storeKey: true
            debug: true
            serviceName: kafka
            principal: pricipal-value
    

    Hope this should help you !!