Search in sources :

Example 1 with DelegationTokenConfig

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);
    }
}
Also used : Connector(org.apache.accumulo.core.client.Connector) DelegationTokenConfig(org.apache.accumulo.core.client.admin.DelegationTokenConfig) KerberosToken(org.apache.accumulo.core.client.security.tokens.KerberosToken) UndeclaredThrowableException(java.lang.reflect.UndeclaredThrowableException) AccumuloSecurityException(org.apache.accumulo.core.client.AccumuloSecurityException) File(java.io.File) TableNotFoundException(org.apache.accumulo.core.client.TableNotFoundException) TableExistsException(org.apache.accumulo.core.client.TableExistsException) AccumuloSecurityException(org.apache.accumulo.core.client.AccumuloSecurityException) UndeclaredThrowableException(java.lang.reflect.UndeclaredThrowableException) AccumuloException(org.apache.accumulo.core.client.AccumuloException) UserGroupInformation(org.apache.hadoop.security.UserGroupInformation) Test(org.junit.Test)

Example 2 with DelegationTokenConfig

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);
}
Also used : Connector(org.apache.accumulo.core.client.Connector) AuthenticationToken(org.apache.accumulo.core.client.security.tokens.AuthenticationToken) DelegationTokenConfig(org.apache.accumulo.core.client.admin.DelegationTokenConfig) KerberosToken(org.apache.accumulo.core.client.security.tokens.KerberosToken) BatchScanner(org.apache.accumulo.core.client.BatchScanner) Range(org.apache.accumulo.core.data.Range) TableNotFoundException(org.apache.accumulo.core.client.TableNotFoundException) TableExistsException(org.apache.accumulo.core.client.TableExistsException) AccumuloSecurityException(org.apache.accumulo.core.client.AccumuloSecurityException) UndeclaredThrowableException(java.lang.reflect.UndeclaredThrowableException) AccumuloException(org.apache.accumulo.core.client.AccumuloException) BatchWriterConfig(org.apache.accumulo.core.client.BatchWriterConfig) BatchWriter(org.apache.accumulo.core.client.BatchWriter) Mutation(org.apache.accumulo.core.data.Mutation) UserGroupInformation(org.apache.hadoop.security.UserGroupInformation) Test(org.junit.Test)

Example 3 with DelegationTokenConfig

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());
}
Also used : Connector(org.apache.accumulo.core.client.Connector) AuthenticationToken(org.apache.accumulo.core.client.security.tokens.AuthenticationToken) DelegationTokenConfig(org.apache.accumulo.core.client.admin.DelegationTokenConfig) KerberosToken(org.apache.accumulo.core.client.security.tokens.KerberosToken) DelegationTokenImpl(org.apache.accumulo.core.client.impl.DelegationTokenImpl) TableNotFoundException(org.apache.accumulo.core.client.TableNotFoundException) TableExistsException(org.apache.accumulo.core.client.TableExistsException) AccumuloSecurityException(org.apache.accumulo.core.client.AccumuloSecurityException) UndeclaredThrowableException(java.lang.reflect.UndeclaredThrowableException) AccumuloException(org.apache.accumulo.core.client.AccumuloException) UserGroupInformation(org.apache.hadoop.security.UserGroupInformation) Test(org.junit.Test)

Example 4 with DelegationTokenConfig

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);
}
Also used : Connector(org.apache.accumulo.core.client.Connector) Instance(org.apache.accumulo.core.client.Instance) DelegationTokenConfig(org.apache.accumulo.core.client.admin.DelegationTokenConfig) KerberosToken(org.apache.accumulo.core.client.security.tokens.KerberosToken) DelegationTokenImpl(org.apache.accumulo.core.client.impl.DelegationTokenImpl) AuthenticationTokenIdentifier(org.apache.accumulo.core.client.impl.AuthenticationTokenIdentifier) AuthenticationToken(org.apache.accumulo.core.client.security.tokens.AuthenticationToken) KerberosToken(org.apache.accumulo.core.client.security.tokens.KerberosToken) PasswordToken(org.apache.accumulo.core.client.security.tokens.PasswordToken) DelegationToken(org.apache.accumulo.core.client.security.tokens.DelegationToken) Token(org.apache.hadoop.security.token.Token) TableOfflineException(org.apache.accumulo.core.client.TableOfflineException) TableNotFoundException(org.apache.accumulo.core.client.TableNotFoundException) TableDeletedException(org.apache.accumulo.core.client.TableDeletedException) AccumuloSecurityException(org.apache.accumulo.core.client.AccumuloSecurityException) IOException(java.io.IOException) AccumuloException(org.apache.accumulo.core.client.AccumuloException)

Example 5 with DelegationTokenConfig

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;
}
Also used : Connector(org.apache.accumulo.core.client.Connector) AuthenticationToken(org.apache.accumulo.core.client.security.tokens.AuthenticationToken) DelegationTokenConfig(org.apache.accumulo.core.client.admin.DelegationTokenConfig) KerberosToken(org.apache.accumulo.core.client.security.tokens.KerberosToken) AccumuloSecurityException(org.apache.accumulo.core.client.AccumuloSecurityException) UserGroupInformation(org.apache.hadoop.security.UserGroupInformation)

Aggregations

DelegationTokenConfig (org.apache.accumulo.core.client.admin.DelegationTokenConfig)17 AccumuloSecurityException (org.apache.accumulo.core.client.AccumuloSecurityException)13 Connector (org.apache.accumulo.core.client.Connector)12 KerberosToken (org.apache.accumulo.core.client.security.tokens.KerberosToken)12 AccumuloException (org.apache.accumulo.core.client.AccumuloException)11 TableNotFoundException (org.apache.accumulo.core.client.TableNotFoundException)11 AuthenticationToken (org.apache.accumulo.core.client.security.tokens.AuthenticationToken)11 TableExistsException (org.apache.accumulo.core.client.TableExistsException)8 UserGroupInformation (org.apache.hadoop.security.UserGroupInformation)8 Test (org.junit.Test)7 UndeclaredThrowableException (java.lang.reflect.UndeclaredThrowableException)6 AuthenticationTokenIdentifier (org.apache.accumulo.core.client.impl.AuthenticationTokenIdentifier)6 DelegationTokenImpl (org.apache.accumulo.core.client.impl.DelegationTokenImpl)6 Instance (org.apache.accumulo.core.client.Instance)5 Token (org.apache.hadoop.security.token.Token)5 IOException (java.io.IOException)4 DelegationToken (org.apache.accumulo.core.client.security.tokens.DelegationToken)4 PasswordToken (org.apache.accumulo.core.client.security.tokens.PasswordToken)4 MutationsRejectedException (org.apache.accumulo.core.client.MutationsRejectedException)2 TableDeletedException (org.apache.accumulo.core.client.TableDeletedException)2