So far in the series, I have covered how to configure SASL with PlainText (Part 1) and how to have different listeners for broker and consumers (Part 2)
In this part, I would dissect the org.apache.kafka.common.security.plain.PlainLoginModule which was configured for SASL with PlainText in Part 1 of this series. This would give insight into developing your custom LoginModule over SASL.
In the static block of the PlainLoginModule class, we are initializing the Sasl Server Provider
In this part, I would dissect the org.apache.kafka.common.security.plain.PlainLoginModule which was configured for SASL with PlainText in Part 1 of this series. This would give insight into developing your custom LoginModule over SASL.
PlainLoginModule:
The same class PlainLoginModule is used for dual purpose which makes it confusing.public class PlainLoginModule implements LoginModule { private static final String USERNAME_CONFIG = "username"; private static final String PASSWORD_CONFIG = "password";static { PlainSaslServerProvider.initialize(); }
public PlainLoginModule() { } public void initialize(Subject subject, CallbackHandler callbackHandler, Map<String, ?> sharedState, Map<String, ?> options) { String username = (String)options.get("username"); if(username != null) { subject.getPublicCredentials().add(username); } String password = (String)options.get("password"); if(password != null) { subject.getPrivateCredentials().add(password); } } public boolean login() throws LoginException { return true; } public boolean logout() throws LoginException { return true; } public boolean commit() throws LoginException { return true; } public boolean abort() throws LoginException { return false; }}
- The Broker to pass in username and password to authenticate against other Brokers
- The Broker to initialize a Server Provider which supports authentication using SASL
In the initialize method of the LoginModule, the Broker adds the configured username and password in the Subject.
This Subject is used by this broker to send in the username/password for authentication by the other user.
public void initialize(Subject subject, CallbackHandler callbackHandler, Map<String, ?> sharedState, Map<String, ?> options) { String username = (String)options.get("username"); if(username != null) { subject.getPublicCredentials().add(username); } String password = (String)options.get("password"); if(password != null) { subject.getPrivateCredentials().add(password); } }
static {
PlainSaslServerProvider.initialize();
}
PlainLoginModule is used to configure the SASL server provider in the Kafka Broker.
The Broker uses the SASL server Provider to authenticate the in-coming call to the broker.
In the initialize method of PlainSaslServerProvider, we are configuring PlainSaslServerProvider as a Security Provider.
The PlainSaslServerProvider configures PlainSaslServerFactory as the SaslServerFactory.
public class PlainSaslServerProvider extends Provider { private static final long serialVersionUID = 1L; protected PlainSaslServerProvider() { super("Simple SASL/PLAIN Server Provider", 1.0D, "Simple SASL/PLAIN Server Provider for Kafka"); super.put("SaslServerFactory.PLAIN", PlainSaslServerFactory.class.getName()); } public static void initialize() { Security.addProvider(new PlainSaslServerProvider()); } }
The PlainSaslServerFactory provides PlainSaslServer as the SaslServer.
PlainSaslServer evaluates the username/password in the evaluateResponse method.