Kafka 2.0.0自定义AuthenticateCallbackHandler实现失败求助
Let's walk through the most likely issues that could be causing your "Invalid username or password" error when using a custom AuthenticateCallbackHandler with Kafka 2.0.0:
1. Broker JAAS Configuration Mistakes
First, double-check your broker_jaas.conf—this is a common source of errors. For a custom callback handler with Plain authentication, your config should look like this (note the correct parameter name for the callback handler):
KafkaServer { org.apache.kafka.common.security.plain.PlainLoginModule required username="admin" # Broker's own admin credentials password="admin-secret" callbackHandlerClass="com.your.package.CustomAuthenticateCallbackHandler"; # Point to your handler class };
- Ensure you're using
callbackHandlerClass, notloginModuleClass(that's for custom login modules, not callback handlers). - In your Docker Compose config, confirm you're mounting the
broker_jaas.conffile correctly and passing it to Kafka viaKAFKA_OPTS:environment: - KAFKA_OPTS=-Djava.security.auth.login.config=/path/to/broker_jaas.conf volumes: - ./broker_jaas.conf:/path/to/broker_jaas.conf
2. Custom Callback Handler Implementation Issues
Verify your handler class correctly implements AuthenticateCallbackHandler and handles the required callbacks properly:
- Make sure you override all three methods:
configure,handle, andclose. - In the
handlemethod, explicitly validate the username and password forPlainAuthenticateCallback:import javax.security.auth.callback.Callback; import javax.security.auth.callback.NameCallback; import javax.security.auth.callback.PlainAuthenticateCallback; import javax.security.auth.callback.UnsupportedCallbackException; import java.io.IOException; import java.util.Arrays; import org.apache.kafka.common.security.auth.AuthenticateCallbackHandler; public class CustomAuthenticateCallbackHandler implements AuthenticateCallbackHandler { @Override public void configure(java.util.Map<String, ?> configs, String saslMechanism, java.util.List<javax.security.auth.login.AppConfigurationEntry> jaasConfigEntries) { // Add any initialization logic here } @Override public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException { for (Callback callback : callbacks) { if (callback instanceof PlainAuthenticateCallback) { PlainAuthenticateCallback authCallback = (PlainAuthenticateCallback) callback; String username = authCallback.username(); char[] password = authCallback.password(); // Validate against your test credentials boolean isValid = "test".equals(username) && Arrays.equals("test".toCharArray(), password); authCallback.authenticated(isValid); } else if (callback instanceof NameCallback) { // For service-side handlers, this can just use the default name ((NameCallback) callback).setName(((NameCallback) callback).getDefaultName()); } else { throw new UnsupportedCallbackException(callback, "Unrecognized callback type"); } } } @Override public void close() { // Cleanup logic if needed } } - Confirm the method signatures match Kafka 2.0.0's API—even small mismatches (like missing generics) can prevent the handler from loading correctly.
3. Jar Loading & Classpath Issues
Your custom handler jar needs to be accessible to Kafka's classpath in the Docker container:
- Mount the jar to Kafka's
libsdirectory (e.g.,/opt/kafka/libs/) via Docker Compose:volumes: - ./custom-handler.jar:/opt/kafka/libs/custom-handler.jar - Alternatively, set the
CLASSPATHenvironment variable to include your jar's path. - To verify, exec into the Kafka container and check if the jar exists and is in the classpath:
docker exec -it <kafka-container-id> bash ls /opt/kafka/libs/custom-handler.jar echo $CLASSPATH
4. Client Configuration Checks
Even though the error is server-side, double-check your cli-client.properties to rule out client-side mistakes:
security.protocol=SASL_PLAINTEXT sasl.mechanism=PLAIN sasl.jaas.config=org.apache.kafka.common.security.plain.PlainLoginModule required username="test" password="test";
- Ensure there's no trailing whitespace in the
sasl.jaas.configvalue, and the semicolon at the end is present. - You don't need a custom callback handler on the client side unless you're overriding client-side authentication logic—stick to the default handler for testing.
5. Enable Debug Logs for Clues
Turn on Kafka's security debug logs to see exactly what's happening during authentication:
- Add this environment variable to your Docker Compose Kafka service:
environment: - KAFKA_LOG4J_LOGGERS="kafka.security=DEBUG,org.apache.kafka.common.security=DEBUG" - Look for logs indicating whether your custom handler was loaded successfully, or if there's a
ClassNotFoundException,NoSuchMethodError, or other error that points to a problem with your implementation or classpath.
内容的提问来源于stack exchange,提问作者Roy van der Valk

