use of org.apache.zookeeper.SaslClientCallbackHandler in project zookeeper by apache.
the class SecurityUtils method createSaslClient.
/**
* Create an instance of a SaslClient. It will return null if there is an exception.
*
* @param subject subject
* @param servicePrincipal principal
* @param protocol name of the protocol for which the authentication is being performed
* @param serverName name of the server to authenticate to
* @param LOG logger
* @param entity can be either zookeeper client or quorum learner
*
* @return saslclient object
* @throws SaslException
*/
public static SaslClient createSaslClient(final Subject subject, final String servicePrincipal, final String protocol, final String serverName, final Logger LOG, final String entity) throws SaslException {
SaslClient saslClient;
// mechanism to use: if empty, use DIGEST-MD5; otherwise, use GSSAPI.
if (subject.getPrincipals().isEmpty()) {
// no principals: must not be GSSAPI: use DIGEST-MD5 mechanism
// instead.
LOG.info("{} will use DIGEST-MD5 as SASL mechanism.", entity);
String[] mechs = { "DIGEST-MD5" };
String username = (String) (subject.getPublicCredentials().toArray()[0]);
String password = (String) (subject.getPrivateCredentials().toArray()[0]);
// 'domain' parameter is hard-wired between the server and client
saslClient = Sasl.createSaslClient(mechs, username, protocol, serverName, null, new SaslClientCallbackHandler(password, entity));
return saslClient;
} else {
// GSSAPI.
final Object[] principals = subject.getPrincipals().toArray();
// determine client principal from subject.
final Principal clientPrincipal = (Principal) principals[0];
boolean usingNativeJgss = Boolean.getBoolean("sun.security.jgss.native");
if (usingNativeJgss) {
// """
try {
GSSManager manager = GSSManager.getInstance();
Oid krb5Mechanism = new Oid("1.2.840.113554.1.2.2");
GSSCredential cred = manager.createCredential(null, GSSContext.DEFAULT_LIFETIME, krb5Mechanism, GSSCredential.INITIATE_ONLY);
subject.getPrivateCredentials().add(cred);
LOG.debug("Added private credential to {} principal name: '{}'", entity, clientPrincipal);
} catch (GSSException ex) {
LOG.warn("Cannot add private credential to subject; " + "authentication at the server may fail", ex);
}
}
final KerberosName clientKerberosName = new KerberosName(clientPrincipal.getName());
// assume that server and client are in the same realm (by default;
// unless the system property
// "zookeeper.server.realm" is set).
String serverRealm = System.getProperty("zookeeper.server.realm", clientKerberosName.getRealm());
KerberosName serviceKerberosName = new KerberosName(servicePrincipal + "@" + serverRealm);
final String serviceName = serviceKerberosName.getServiceName();
final String serviceHostname = serviceKerberosName.getHostName();
final String clientPrincipalName = clientKerberosName.toString();
try {
saslClient = Subject.doAs(subject, new PrivilegedExceptionAction<SaslClient>() {
public SaslClient run() throws SaslException {
LOG.info("{} will use GSSAPI as SASL mechanism.", entity);
String[] mechs = { "GSSAPI" };
LOG.debug("creating sasl client: {}={};service={};serviceHostname={}", new Object[] { entity, clientPrincipalName, serviceName, serviceHostname });
SaslClient saslClient = Sasl.createSaslClient(mechs, clientPrincipalName, serviceName, serviceHostname, null, new SaslClientCallbackHandler(null, entity));
return saslClient;
}
});
return saslClient;
} catch (Exception e) {
LOG.error("Exception while trying to create SASL client", e);
return null;
}
}
}
use of org.apache.zookeeper.SaslClientCallbackHandler in project zookeeper by apache.
the class ZooKeeperSaslClient method createSaslClient.
private SaslClient createSaslClient(final String servicePrincipal, final String loginContext) throws LoginException {
try {
if (!initializedLogin) {
synchronized (this) {
if (login == null) {
if (LOG.isDebugEnabled()) {
LOG.debug("JAAS loginContext is: " + loginContext);
}
// note that the login object is static: it's shared amongst all zookeeper-related connections.
// in order to ensure the login is initialized only once, it must be synchronized the code snippet.
login = new Login(loginContext, new SaslClientCallbackHandler(null, "Client"), clientConfig);
login.startThreadIfNeeded();
initializedLogin = true;
}
}
}
return SecurityUtils.createSaslClient(login.getSubject(), servicePrincipal, "zookeeper", "zk-sasl-md5", LOG, "Client");
} catch (LoginException e) {
// We throw LoginExceptions...
throw e;
} catch (Exception e) {
// ..but consume (with a log message) all other types of exceptions.
LOG.error("Exception while trying to create SASL client: " + e);
return null;
}
}
Aggregations