com.datastax.driver.auth.PrivilegedSaslClient Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of cassandra-driver-dse Show documentation
Show all versions of cassandra-driver-dse Show documentation
Extensions to the CQL driver for use with DataStax Enterprise.
/*
* Copyright (C) 2012-2015 DataStax Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.datastax.driver.auth;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.security.auth.Subject;
import javax.security.auth.callback.CallbackHandler;
import javax.security.sasl.Sasl;
import javax.security.sasl.SaslClient;
import javax.security.sasl.SaslException;
import java.security.PrivilegedAction;
import java.util.HashMap;
import java.util.Map;
/**
* Wrapper around {@code SaslClient}, which performs necessary parts of
* the authentication protocol as {@code PrivilegedAction}s with the
* assumed identity of the {@code Subject} supplied in the constructor.
*/
public class PrivilegedSaslClient
{
private static final Logger logger = LoggerFactory.getLogger(PrivilegedSaslClient.class);
public static final Map DEFAULT_PROPERTIES = new HashMap()
{{
put(Sasl.SERVER_AUTH, "true");
put(Sasl.QOP, "auth");
}};
private static final byte[] EMPTY_BYTE_ARRAY = new byte[0];
/**
* Used to respond to server challenges with SASL tokens
* represented as byte arrays.
*/
private final SaslClient saslClient;
/**
* The identity we intend to use when we authenticate with the server
*/
private Subject clientIdentity;
public PrivilegedSaslClient(final Subject clientIdentity,
final String[] mechanisms,
final String authzId,
final String protocol,
final String hostname,
final Map properties,
final CallbackHandler callbackHandler)
{
logger.trace("Initalising SASL client");
this.clientIdentity = clientIdentity;
saslClient = Subject.doAs(this.clientIdentity, new PrivilegedAction()
{
@Override
public javax.security.sasl.SaslClient run()
{
try
{
return Sasl.createSaslClient(
mechanisms,
authzId,
protocol,
hostname,
properties,
callbackHandler);
} catch (Exception e)
{
logger.error("Error initialising SASL client", e);
throw new RuntimeException(e);
}
}
});
logger.trace("SASL client initialised");
}
/**
* Generate an initial token to start the SASL handshake with server.
* @return SaslTokenRequestMessage message to be sent to server.
*/
public byte[] getInitialResponse()
{
logger.trace("Initialising SASL handshake from client");
byte[] initialResponse = null;
if (saslClient.hasInitialResponse())
{
initialResponse = Subject.doAs(clientIdentity, new PrivilegedAction()
{
@Override
public byte[] run()
{
try
{
return saslClient.evaluateChallenge(EMPTY_BYTE_ARRAY);
} catch (Exception e)
{
throw new RuntimeException(e);
}
}
});
}
return initialResponse;
}
/**
* Respond to server's SASL token
* @param challenge contains server's SASL token
* @return client's response SASL token, which will be null if authentication is complete
*/
public byte[] evaluateChallenge(final byte[] challenge)
{
logger.trace("Evaluating SASL server token");
if (saslClient.isComplete())
{
return null;
}
byte[] retval = Subject.doAs(clientIdentity, new PrivilegedAction()
{
@Override
public byte[] run()
{
try
{
logger.trace("SASL client evaluating challenge");
byte[] retval = saslClient.evaluateChallenge(challenge);
logger.trace("SASL client is complete = " + saslClient.isComplete());
return retval;
}
catch (SaslException e)
{
logger.error("Failed to generate response to SASL server's token:", e);
throw new RuntimeException(e);
}
}
});
return retval;
}
/**
* Is the SASL negotiation with the server complete
* @return true iff SASL authentication has successfully completed
*/
public boolean isComplete()
{
return saslClient.isComplete();
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy