4.2. Configure Node Security in Library Mode In Library mode, node authentication is configured directly in the JGroups configuration. JGroups can be configured so that nodes must authenticate each other when joining or merging with a cluster. The authentication uses SASL and is enabled by adding the SASL protocol to your JGroups XML configuration. SASL relies on JAAS notions, such as CallbackHandlers , to obtain certain information necessary for the authentication handshake. Users must supply their own CallbackHandlers on both client and server sides. Important The JAAS API is only available when configuring user authentication and authorization, and is not available for node security. Note In the provided example, CallbackHandler classes are examples only, and not contained in the Red Hat JBoss Data Grid release. Users must provide the appropriate CallbackHandler classes for their specific LDAP implementation. Example 4.4. Setting Up SASL Authentication in JGroups The above example uses the DIGEST-MD5 mechanism. Each node must declare the user and password it will use when joining the cluster. Important The SASL protocol must be placed before the GMS protocol in order for authentication to take effect. The following example demonstrates how to implement a CallbackHandler class. In this example, login and password are checked against values provided via Java properties when JBoss Data Grid is started, and authorization is checked against role which is defined in the class ( "test_user" ). Example 4.5. Callback Handler Class For authentication, specify the javax.security.auth.callback.NameCallback and javax.security.auth.callback.PasswordCallback callbacks For authorization, specify the callbacks required for authentication, as well as specifying the javax.security.sasl.AuthorizeCallback callback. Report a bug 4.2.1. Configure Node Authentication for Library Mode (DIGEST-MD5) The behavior of a node differs depending on whether it is the coordinator node or any other node. The coordinator acts as the SASL server, with the joining or merging nodes behaving as SASL clients. When using the DIGEST-MD5 mechanism in Library mode, the server and client callback must be specified so that the server and client are aware of how to obtain the credentials. Therefore, two CallbackHandlers are required: The server_callback_handler_class is used by the coordinator. The client_callback_handler_class is used by other nodes. The following example demonstrates these CallbackHandlers . Example 4.6. Callback Handlers JGroups is designed so that all nodes are able to act as coordinator or client depending on cluster behavior, so if the current coordinator node goes down, the node in the succession chain will become the coordinator. Given this behavior, both server and client callback handlers must be identified within SASL for Red Hat JBoss Data Grid implementations. Report a bug 4.2.2. Configure Node Authentication for Library Mode (GSSAPI) When performing node authentication in Library mode using the GSSAPI mechanism, the login_module_name parameter must be specified instead of callback . This login module is used to obtain a valid Kerberos ticket, which is used to authenticate a client to the server. The server_name must also be specified, as the client principal is constructed as jgroups/USDserver_name@REALM . Example 4.7. Specifying the login module and server on the coordinator node On the coordinator node, the server_callback_handler_class must be specified for node authorization. This will determine if the authenticated joining node has permission to join the cluster. Note The server principal is always constructed as jgroups/server_name , therefore the server principal in Kerberos must also be jgroups/server_name . For example, if the server name in Kerberos is jgroups/node1/mycache , then the server name must be node1/mycache . Report a bug 4.2.3. Node Authorization in Library Mode The SASL protocol in JGroups is concerned only with the authentication process. To implement node authorization, you can do so within the server callback handler by throwing an Exception. The following example demonstrates this. Example 4.8. Implementing Node Authorization Report a bug

Commands:
<SASL mech="DIGEST-MD5" client_name="node_user" client_password="node_password" server_callback_handler_class="org.example.infinispan.security.JGroupsSaslServerCallbackHandler" client_callback_handler_class="org.example.infinispan.security.JGroupsSaslClientCallbackHandler" sasl_props="com.sun.security.sasl.digest.realm=test_realm" />
public class SaslPropAuthUserCallbackHandler implements CallbackHandler { private static final String APPROVED_USER = "test_user"; private final String name; private final char[] password; private final String realm; public SaslPropAuthUserCallbackHandler() { this.name = System.getProperty("sasl.username"); this.password = System.getProperty("sasl.password").toCharArray(); this.realm = System.getProperty("sasl.realm"); } @Override public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException { for (Callback callback : callbacks) { if (callback instanceof PasswordCallback) { ((PasswordCallback) callback).setPassword(password); } else if (callback instanceof NameCallback) { ((NameCallback) callback).setName(name); } else if (callback instanceof AuthorizeCallback) { AuthorizeCallback authorizeCallback = (AuthorizeCallback) callback; if (APPROVED_USER.equals(authorizeCallback.getAuthorizationID())) { authorizeCallback.setAuthorized(true); } else { authorizeCallback.setAuthorized(false); } } else if (callback instanceof RealmCallback) { RealmCallback realmCallback = (RealmCallback) callback; realmCallback.setText(realm); } else { throw new UnsupportedCallbackException(callback); } } } }
<SASL mech="DIGEST-MD5" client_name="node_name" client_password="node_password" client_callback_handler_class="USD{CLIENT_CALLBACK_HANDLER_IN_CLASSPATH}" server_callback_handler_class="USD{SERVER_CALLBACK_HANDLER_IN_CLASSPATH}" sasl_props="com.sun.security.sasl.digest.realm=test_realm" />
<SASL mech="GSSAPI" server_name="node0/clustered" login_module_name="krb-node0" server_callback_handler_class="org.infinispan.test.integration.security.utils.SaslPropCallbackHandler" />
public class AuthorizingServerCallbackHandler implements CallbackHandler { @Override public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException { for (Callback callback : callbacks) { <!-- Additional configuration information here --> if (callback instanceof AuthorizeCallback) { AuthorizeCallback acb = (AuthorizeCallback) callback; if (!"myclusterrole".equals(acb.getAuthenticationID()))) { throw new SecurityException("Unauthorized node " +user); } <!-- Additional configuration information here --> } } }