use of org.apache.zookeeper.Login in project hadoop by apache.
the class TestSecureRegistry method testLowlevelZKSaslLogin.
/**
* this is a cut and paste of some of the ZK internal code that was
* failing on windows and swallowing its exceptions
*/
@Test
public void testLowlevelZKSaslLogin() throws Throwable {
RegistrySecurity.bindZKToServerJAASContext(ZOOKEEPER_SERVER_CONTEXT);
String serverSection = System.getProperty(ZooKeeperSaslServer.LOGIN_CONTEXT_NAME_KEY, ZooKeeperSaslServer.DEFAULT_LOGIN_CONTEXT_NAME);
assertEquals(ZOOKEEPER_SERVER_CONTEXT, serverSection);
AppConfigurationEntry[] entries;
entries = javax.security.auth.login.Configuration.getConfiguration().getAppConfigurationEntry(serverSection);
assertNotNull("null entries", entries);
SaslServerCallbackHandler saslServerCallbackHandler = new SaslServerCallbackHandler(javax.security.auth.login.Configuration.getConfiguration());
Login login = new Login(serverSection, saslServerCallbackHandler);
try {
login.startThreadIfNeeded();
} finally {
login.shutdown();
}
}
use of org.apache.zookeeper.Login in project fabric8 by jboss-fuse.
the class ZooKeeperSaslClient method createSaslClient.
private synchronized SaslClient createSaslClient(final String servicePrincipal, final String loginContext) throws LoginException {
try {
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.
// createSaslClient() must be declared synchronized so that login is initialized only once.
login = new Login(loginContext, new ClientCallbackHandler(null));
login.startThreadIfNeeded();
}
Subject subject = login.getSubject();
SaslClient saslClient;
// 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("Client will use DIGEST-MD5 as SASL mechanism.");
String[] mechs = { "DIGEST-MD5" };
String username = (String) (subject.getPublicCredentials().toArray()[0]);
String password = (String) (subject.getPrivateCredentials().toArray()[0]);
// "zk-sasl-md5" is a hard-wired 'domain' parameter shared with zookeeper server code (see ServerCnxnFactory.java)
saslClient = Sasl.createSaslClient(mechs, username, "zookeeper", "zk-sasl-md5", null, new ClientCallbackHandler(password));
return saslClient;
} else {
// GSSAPI.
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);
if (LOG.isDebugEnabled()) {
LOG.debug("Added private credential to subject: " + cred);
}
} catch (GSSException ex) {
LOG.warn("Cannot add private credential to subject; " + "authentication at the server may fail", ex);
}
}
final Object[] principals = subject.getPrincipals().toArray();
// determine client principal from subject.
final Principal clientPrincipal = (Principal) principals[0];
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("Client will use GSSAPI as SASL mechanism.");
String[] mechs = { "GSSAPI" };
LOG.debug("creating sasl client: client=" + clientPrincipalName + ";service=" + serviceName + ";serviceHostname=" + serviceHostname);
SaslClient saslClient = Sasl.createSaslClient(mechs, clientPrincipalName, serviceName, serviceHostname, null, new ClientCallbackHandler(null));
return saslClient;
}
});
return saslClient;
} catch (Exception e) {
LOG.error("Exception while trying to create SASL client", e);
e.printStackTrace();
return null;
}
}
} 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;
}
}
use of org.apache.zookeeper.Login in project jstorm by alibaba.
the class KerberosSaslTransportPlugin method getServerTransportFactory.
public TTransportFactory getServerTransportFactory() throws IOException {
// create an authentication callback handler
CallbackHandler server_callback_handler = new ServerCallbackHandler(login_conf, storm_conf);
// login our principal
Subject subject = null;
try {
// specify a configuration object to be used
Configuration.setConfiguration(login_conf);
// now login
Login login = new Login(AuthUtils.LOGIN_CONTEXT_SERVER, server_callback_handler);
subject = login.getSubject();
} catch (LoginException ex) {
LOG.error("Server failed to login in principal:" + ex, ex);
throw new RuntimeException(ex);
}
// check the credential of our principal
if (subject.getPrivateCredentials(KerberosTicket.class).isEmpty()) {
throw new RuntimeException("Fail to verify user principal with section \"" + AuthUtils.LOGIN_CONTEXT_SERVER + "\" in login configuration file " + login_conf);
}
String principal = AuthUtils.get(login_conf, AuthUtils.LOGIN_CONTEXT_SERVER, "principal");
LOG.debug("principal:" + principal);
KerberosName serviceKerberosName = new KerberosName(principal);
String serviceName = serviceKerberosName.getServiceName();
String hostName = serviceKerberosName.getHostName();
Map<String, String> props = new TreeMap<String, String>();
props.put(Sasl.QOP, "auth");
props.put(Sasl.SERVER_AUTH, "false");
// create a transport factory that will invoke our auth callback for digest
TSaslServerTransport.Factory factory = new TSaslServerTransport.Factory();
factory.addServerDefinition(KERBEROS, serviceName, hostName, props, server_callback_handler);
// create a wrap transport factory so that we could apply user credential during connections
TUGIAssumingTransportFactory wrapFactory = new TUGIAssumingTransportFactory(factory, subject);
LOG.info("SASL GSSAPI transport factory will be used");
return wrapFactory;
}
use of org.apache.zookeeper.Login in project jstorm by alibaba.
the class KerberosSaslTransportPlugin method connect.
@Override
public TTransport connect(TTransport transport, String serverHost, String asUser) throws TTransportException, IOException {
// create an authentication callback handler
ClientCallbackHandler client_callback_handler = new ClientCallbackHandler(login_conf);
// login our user
Login login = null;
try {
// specify a configuration object to be used
Configuration.setConfiguration(login_conf);
// now login
login = new Login(AuthUtils.LOGIN_CONTEXT_CLIENT, client_callback_handler);
} catch (LoginException ex) {
LOG.error("Server failed to login in principal:" + ex, ex);
throw new RuntimeException(ex);
}
final Subject subject = login.getSubject();
if (subject.getPrivateCredentials(KerberosTicket.class).isEmpty()) {
// error
throw new RuntimeException("Fail to verify user principal with section \"" + AuthUtils.LOGIN_CONTEXT_CLIENT + "\" in login configuration file " + login_conf);
}
final String principal = StringUtils.isBlank(asUser) ? getPrincipal(subject) : asUser;
String serviceName = AuthUtils.get(login_conf, AuthUtils.LOGIN_CONTEXT_CLIENT, "serviceName");
if (serviceName == null) {
serviceName = AuthUtils.SERVICE;
}
Map<String, String> props = new TreeMap<String, String>();
props.put(Sasl.QOP, "auth");
props.put(Sasl.SERVER_AUTH, "false");
LOG.debug("SASL GSSAPI client transport is being established");
final TTransport sasalTransport = new TSaslClientTransport(KERBEROS, principal, serviceName, serverHost, props, null, transport);
// open Sasl transport with the login credential
try {
Subject.doAs(subject, new PrivilegedExceptionAction<Void>() {
public Void run() {
try {
LOG.debug("do as:" + principal);
sasalTransport.open();
} catch (Exception e) {
LOG.error("Client failed to open SaslClientTransport to interact with a server during session initiation: " + e, e);
}
return null;
}
});
} catch (PrivilegedActionException e) {
throw new RuntimeException(e);
}
return sasalTransport;
}
use of org.apache.zookeeper.Login in project zookeeper by apache.
the class ServerCnxnFactory method configureSaslLogin.
/**
* Initialize the server SASL if specified.
*
* If the user has specified a "ZooKeeperServer.LOGIN_CONTEXT_NAME_KEY"
* or a jaas.conf using "java.security.auth.login.config"
* the authentication is required and an exception is raised.
* Otherwise no authentication is configured and no exception is raised.
*
* @throws IOException if jaas.conf is missing or there's an error in it.
*/
protected void configureSaslLogin() throws IOException {
String serverSection = System.getProperty(ZooKeeperSaslServer.LOGIN_CONTEXT_NAME_KEY, ZooKeeperSaslServer.DEFAULT_LOGIN_CONTEXT_NAME);
// Note that 'Configuration' here refers to javax.security.auth.login.Configuration.
AppConfigurationEntry[] entries = null;
SecurityException securityException = null;
try {
entries = Configuration.getConfiguration().getAppConfigurationEntry(serverSection);
} catch (SecurityException e) {
// handle below: might be harmless if the user doesn't intend to use JAAS authentication.
securityException = e;
}
// we throw an exception otherwise we continue without authentication.
if (entries == null) {
String jaasFile = System.getProperty(Environment.JAAS_CONF_KEY);
String loginContextName = System.getProperty(ZooKeeperSaslServer.LOGIN_CONTEXT_NAME_KEY);
if (securityException != null && (loginContextName != null || jaasFile != null)) {
String errorMessage = "No JAAS configuration section named '" + serverSection + "' was found";
if (jaasFile != null) {
errorMessage += " in '" + jaasFile + "'.";
}
if (loginContextName != null) {
errorMessage += " But " + ZooKeeperSaslServer.LOGIN_CONTEXT_NAME_KEY + " was set.";
}
LOG.error(errorMessage);
throw new IOException(errorMessage);
}
return;
}
// jaas.conf entry available
try {
saslServerCallbackHandler = new SaslServerCallbackHandler(Configuration.getConfiguration());
login = new Login(serverSection, saslServerCallbackHandler, new ZKConfig());
setLoginUser(login.getUserName());
login.startThreadIfNeeded();
} catch (LoginException e) {
throw new IOException("Could not configure server because SASL configuration did not allow the " + " ZooKeeper server to authenticate itself properly: " + e);
}
}
Aggregations