use of org.apache.accumulo.core.client.admin.DelegationTokenConfig in project accumulo by apache.
the class KerberosIT method testGetDelegationTokenDenied.
@Test
public void testGetDelegationTokenDenied() throws Exception {
String newUser = testName.getMethodName();
final File newUserKeytab = new File(kdc.getKeytabDir(), newUser + ".keytab");
if (newUserKeytab.exists() && !newUserKeytab.delete()) {
log.warn("Unable to delete {}", newUserKeytab);
}
// Create a new user
kdc.createPrincipal(newUserKeytab, newUser);
final String qualifiedNewUser = kdc.qualifyUser(newUser);
// Login as a normal user
UserGroupInformation ugi = UserGroupInformation.loginUserFromKeytabAndReturnUGI(qualifiedNewUser, newUserKeytab.getAbsolutePath());
try {
ugi.doAs(new PrivilegedExceptionAction<Void>() {
@Override
public Void run() throws Exception {
// As the "root" user, open up the connection and get a delegation token
Connector conn = mac.getConnector(qualifiedNewUser, new KerberosToken());
log.info("Created connector as {}", qualifiedNewUser);
assertEquals(qualifiedNewUser, conn.whoami());
conn.securityOperations().getDelegationToken(new DelegationTokenConfig());
return null;
}
});
} catch (UndeclaredThrowableException ex) {
assertTrue(ex.getCause() instanceof AccumuloSecurityException);
}
}
use of org.apache.accumulo.core.client.admin.DelegationTokenConfig in project accumulo by apache.
the class KerberosIT method testDelegationToken.
@Test
public void testDelegationToken() throws Exception {
final String tableName = getUniqueNames(1)[0];
// Login as the "root" user
UserGroupInformation root = UserGroupInformation.loginUserFromKeytabAndReturnUGI(rootUser.getPrincipal(), rootUser.getKeytab().getAbsolutePath());
log.info("Logged in as {}", rootUser.getPrincipal());
final int numRows = 100, numColumns = 10;
// As the "root" user, open up the connection and get a delegation token
final AuthenticationToken delegationToken = root.doAs(new PrivilegedExceptionAction<AuthenticationToken>() {
@Override
public AuthenticationToken run() throws Exception {
Connector conn = mac.getConnector(rootUser.getPrincipal(), new KerberosToken());
log.info("Created connector as {}", rootUser.getPrincipal());
assertEquals(rootUser.getPrincipal(), conn.whoami());
conn.tableOperations().create(tableName);
BatchWriter bw = conn.createBatchWriter(tableName, new BatchWriterConfig());
for (int r = 0; r < numRows; r++) {
Mutation m = new Mutation(Integer.toString(r));
for (int c = 0; c < numColumns; c++) {
String col = Integer.toString(c);
m.put(col, col, col);
}
bw.addMutation(m);
}
bw.close();
return conn.securityOperations().getDelegationToken(new DelegationTokenConfig());
}
});
// The above login with keytab doesn't have a way to logout, so make a fake user that won't have krb credentials
UserGroupInformation userWithoutPrivs = UserGroupInformation.createUserForTesting("fake_user", new String[0]);
int recordsSeen = userWithoutPrivs.doAs(new PrivilegedExceptionAction<Integer>() {
@Override
public Integer run() throws Exception {
Connector conn = mac.getConnector(rootUser.getPrincipal(), delegationToken);
try (BatchScanner bs = conn.createBatchScanner(tableName, Authorizations.EMPTY, 2)) {
bs.setRanges(Collections.singleton(new Range()));
int recordsSeen = Iterables.size(bs);
return recordsSeen;
}
}
});
assertEquals(numRows * numColumns, recordsSeen);
}
use of org.apache.accumulo.core.client.admin.DelegationTokenConfig in project accumulo by apache.
the class KerberosIT method testRestartedMasterReusesSecretKey.
@Test
public void testRestartedMasterReusesSecretKey() throws Exception {
// Login as the "root" user
UserGroupInformation root = UserGroupInformation.loginUserFromKeytabAndReturnUGI(rootUser.getPrincipal(), rootUser.getKeytab().getAbsolutePath());
log.info("Logged in as {}", rootUser.getPrincipal());
// As the "root" user, open up the connection and get a delegation token
final AuthenticationToken delegationToken1 = root.doAs(new PrivilegedExceptionAction<AuthenticationToken>() {
@Override
public AuthenticationToken run() throws Exception {
Connector conn = mac.getConnector(rootUser.getPrincipal(), new KerberosToken());
log.info("Created connector as {}", rootUser.getPrincipal());
assertEquals(rootUser.getPrincipal(), conn.whoami());
AuthenticationToken token = conn.securityOperations().getDelegationToken(new DelegationTokenConfig());
assertTrue("Could not get tables with delegation token", mac.getConnector(rootUser.getPrincipal(), token).tableOperations().list().size() > 0);
return token;
}
});
log.info("Stopping master");
mac.getClusterControl().stop(ServerType.MASTER);
Thread.sleep(5000);
log.info("Restarting master");
mac.getClusterControl().start(ServerType.MASTER);
// Make sure our original token is still good
root.doAs(new PrivilegedExceptionAction<Void>() {
@Override
public Void run() throws Exception {
Connector conn = mac.getConnector(rootUser.getPrincipal(), delegationToken1);
assertTrue("Could not get tables with delegation token", conn.tableOperations().list().size() > 0);
return null;
}
});
// Get a new token, so we can compare the keyId on the second to the first
final AuthenticationToken delegationToken2 = root.doAs(new PrivilegedExceptionAction<AuthenticationToken>() {
@Override
public AuthenticationToken run() throws Exception {
Connector conn = mac.getConnector(rootUser.getPrincipal(), new KerberosToken());
log.info("Created connector as {}", rootUser.getPrincipal());
assertEquals(rootUser.getPrincipal(), conn.whoami());
AuthenticationToken token = conn.securityOperations().getDelegationToken(new DelegationTokenConfig());
assertTrue("Could not get tables with delegation token", mac.getConnector(rootUser.getPrincipal(), token).tableOperations().list().size() > 0);
return token;
}
});
// A restarted master should reuse the same secret key after a restart if the secret key hasn't expired (1day by default)
DelegationTokenImpl dt1 = (DelegationTokenImpl) delegationToken1;
DelegationTokenImpl dt2 = (DelegationTokenImpl) delegationToken2;
assertEquals(dt1.getIdentifier().getKeyId(), dt2.getIdentifier().getKeyId());
}
use of org.apache.accumulo.core.client.admin.DelegationTokenConfig in project accumulo by apache.
the class AbstractInputFormat method setConnectorInfo.
/**
* Sets the connector information needed to communicate with Accumulo in this job.
*
* <p>
* <b>WARNING:</b> Some tokens, when serialized, divulge sensitive information in the configuration as a means to pass the token to MapReduce tasks. This
* information is BASE64 encoded to provide a charset safe conversion to a string, but this conversion is not intended to be secure. {@link PasswordToken} is
* one example that is insecure in this way; however {@link DelegationToken}s, acquired using
* {@link SecurityOperations#getDelegationToken(DelegationTokenConfig)}, is not subject to this concern.
*
* @param job
* the Hadoop job instance to be configured
* @param principal
* a valid Accumulo user name (user must have Table.CREATE permission)
* @param token
* the user's password
* @since 1.5.0
* @deprecated since 2.0.0; use {@link #setConnectionInfo(Job, ConnectionInfo)} instead.
*/
@Deprecated
public static void setConnectorInfo(Job job, String principal, AuthenticationToken token) throws AccumuloSecurityException {
if (token instanceof KerberosToken) {
log.info("Received KerberosToken, attempting to fetch DelegationToken");
try {
Instance instance = getInstance(job);
Connector conn = instance.getConnector(principal, token);
token = conn.securityOperations().getDelegationToken(new DelegationTokenConfig());
} catch (Exception e) {
log.warn("Failed to automatically obtain DelegationToken, Mappers/Reducers will likely fail to communicate with Accumulo", e);
}
}
// DelegationTokens can be passed securely from user to task without serializing insecurely in the configuration
if (token instanceof DelegationTokenImpl) {
DelegationTokenImpl delegationToken = (DelegationTokenImpl) token;
// Convert it into a Hadoop Token
AuthenticationTokenIdentifier identifier = delegationToken.getIdentifier();
Token<AuthenticationTokenIdentifier> hadoopToken = new Token<>(identifier.getBytes(), delegationToken.getPassword(), identifier.getKind(), delegationToken.getServiceName());
// Add the Hadoop Token to the Job so it gets serialized and passed along.
job.getCredentials().addToken(hadoopToken.getService(), hadoopToken);
}
InputConfigurator.setConnectorInfo(CLASS, job.getConfiguration(), principal, token);
}
use of org.apache.accumulo.core.client.admin.DelegationTokenConfig in project accumulo by apache.
the class MapReduceClientOpts method getToken.
@Override
public AuthenticationToken getToken() {
AuthenticationToken authToken = super.getToken();
// so we need to request a delegation token and use that instead.
if (authToken instanceof KerberosToken) {
log.info("Received KerberosToken, fetching DelegationToken for MapReduce");
final KerberosToken krbToken = (KerberosToken) authToken;
try {
UserGroupInformation user = UserGroupInformation.getCurrentUser();
if (!user.hasKerberosCredentials()) {
throw new IllegalStateException("Expected current user to have Kerberos credentials");
}
String newPrincipal = user.getUserName();
log.info("Obtaining delegation token for {}", newPrincipal);
setPrincipal(newPrincipal);
Connector conn = getInstance().getConnector(newPrincipal, krbToken);
// Do the explicit check to see if the user has the permission to get a delegation token
if (!conn.securityOperations().hasSystemPermission(conn.whoami(), SystemPermission.OBTAIN_DELEGATION_TOKEN)) {
log.error("{} doesn't have the {} SystemPermission neccesary to obtain a delegation token. MapReduce tasks cannot automatically use the client's" + " credentials on remote servers. Delegation tokens provide a means to run MapReduce without distributing the user's credentials.", user.getUserName(), SystemPermission.OBTAIN_DELEGATION_TOKEN.name());
throw new IllegalStateException(conn.whoami() + " does not have permission to obtain a delegation token");
}
// Get the delegation token from Accumulo
return conn.securityOperations().getDelegationToken(new DelegationTokenConfig());
} catch (Exception e) {
final String msg = "Failed to acquire DelegationToken for use with MapReduce";
log.error(msg, e);
throw new RuntimeException(msg, e);
}
}
return authToken;
}
Aggregations