Telemetry channel JAAS configuration

Configure JAAS to authenticate the Username sent by the client.

The IBM® MQ administrator configures which MQTT channels require client authentication using JAAS. Specify the name of a JAAS configuration for each channel that is to perform JAAS authentication. Channels can all use the same JAAS configuration, or they can use different JAAS configurations. The configurations are defined in WMQData directory\qmgrs\qMgrName\mqxr\jaas.config.

The jaas.config file is organized by JAAS configuration name. Under each configuration name is a list of Login configurations; see Figure 1.

JAAS provides four standard Login modules. The standard NT and UNIX Login modules are of limited value.
JndiLoginModule
Authenticates against a directory service configured under JNDI ( Java Naming and Directory Interface).
Krb5LoginModule
Authenticates using Kerberos protocols.
NTLoginModule
Authenticates using the NT security information for the current user.
UnixLoginModule
Authenticates using the UNIX security information for the current user.
The problem with using NTLoginModule or UnixLoginModule is that the telemetry (MQXR) service runs with the mqm identity, and not the identity of the MQTT channel. mqm is the identity passed to NTLoginModule or UnixLoginModule for authentication, and not the identity of the client.

To overcome this problem, write your own Login module, or use the other standard Login modules. A sample JAASLoginModule.java is supplied with IBM MQ Telemetry. It is an implementation of the javax.security.auth.spi.LoginModule interface. Use it to develop your own authentication method.

Any new LoginModule classes you provide must be on the class path of the telemetry (MQXR) service. Do not place your classes in IBM MQ directories that are in the class path. Create your own directories, and define the whole class path for the telemetry (MQXR) service.

You can augment the class path used by the telemetry (MQXR) service by setting class path in the service.env file. CLASSPATH must be capitalized, and the class path statement can only contain literals. You cannot use variables in the CLASSPATH; for example CLASSPATH=%CLASSPATH% is incorrect. The telemetry (MQXR) service sets its own classpath. The CLASSPATH defined in service.env is added to it.

The telemetry (MQXR) service provides two callbacks that return the Username and the Password for a client connected to the MQTT channel. The Username and Password are set in the MqttConnectOptions object. See Figure 2 for an example of how to access Username and Password.

Examples

An example of a JAAS configuration file with one named configuration, MQXRConfig.
Figure 1. Sample jaas.config file

MQXRConfig {
samples.JAASLoginModule required debug=true;
//com.ibm.security.auth.module.NTLoginModule required;
//com.ibm.security.auth.module.Krb5LoginModule required
//         principal=principal@your_realm
//         useDefaultCcache=TRUE
//         renewTGT=true;
//com.sun.security.auth.module.NTLoginModule required;
//com.sun.security.auth.module.UnixLoginModule required;
//com.sun.security.auth.module.Krb5LoginModule required
//         useTicketCache="true"
//         ticketCache="${user.home}${/}tickets";
};
An example of a JAAS Login module coded to receive the Username and Password provided by an MQTT client.
Figure 2. Sample JAASLoginModule.Login() method

public boolean login()
throws javax.security.auth.login.LoginException {
javax.security.auth.callback.Callback[] callbacks =
new javax.security.auth.callback.Callback[2];
callbacks[0] = new javax.security.auth.callback.NameCallback("NameCallback");
callbacks[1] = new javax.security.auth.callback.PasswordCallback(
"PasswordCallback", false);
try {
callbackHandler.handle(callbacks);
String username = ((javax.security.auth.callback.NameCallback) callbacks[0])
.getName();
char[] password = ((javax.security.auth.callback.PasswordCallback) callbacks[1])
.getPassword();
 // Accept everything.
if (true) {
loggedIn = true;
} else
throw new javax.security.auth.login.FailedLoginException("Login failed");

principal= new JAASPrincipal(username);

} catch (java.io.IOException exception) {
throw new javax.security.auth.login.LoginException(exception.toString());
} catch (javax.security.auth.callback.UnsupportedCallbackException exception) {
throw new javax.security.auth.login.LoginException(exception.toString());
}

return loggedIn;
}