Search in sources :

Example 1 with OzoneTokenIdentifier

use of org.apache.hadoop.ozone.security.OzoneTokenIdentifier in project ozone by apache.

the class OzoneClientFactory method getOzoneClient.

/**
 * Create OzoneClient for token renew/cancel operations.
 * @param conf Configuration to be used for OzoneCient creation
 * @param token ozone token is involved
 * @return
 * @throws IOException
 */
public static OzoneClient getOzoneClient(Configuration conf, Token<OzoneTokenIdentifier> token) throws IOException {
    Preconditions.checkNotNull(token, "Null token is not allowed");
    OzoneTokenIdentifier tokenId = new OzoneTokenIdentifier();
    ByteArrayInputStream buf = new ByteArrayInputStream(token.getIdentifier());
    DataInputStream in = new DataInputStream(buf);
    tokenId.readFields(in);
    String omServiceId = tokenId.getOmServiceId();
    OzoneConfiguration ozoneConf = OzoneConfiguration.of(conf);
    // Must check with OzoneConfiguration so that ozone-site.xml is loaded.
    if (StringUtils.isNotEmpty(omServiceId)) {
        // new OM should always issue token with omServiceId
        if (!OmUtils.isServiceIdsDefined(ozoneConf) && omServiceId.equals(OzoneConsts.OM_SERVICE_ID_DEFAULT)) {
            // Non-HA or single-node Ratis HA
            return OzoneClientFactory.getRpcClient(ozoneConf);
        } else if (OmUtils.isOmHAServiceId(ozoneConf, omServiceId)) {
            // HA with matching service id
            return OzoneClientFactory.getRpcClient(omServiceId, ozoneConf);
        } else {
            // HA with mismatched service id
            throw new IOException("Service ID specified " + omServiceId + " does not match" + " with " + OZONE_OM_SERVICE_IDS_KEY + " defined in the " + "configuration. Configured " + OZONE_OM_SERVICE_IDS_KEY + " are" + ozoneConf.getTrimmedStringCollection(OZONE_OM_SERVICE_IDS_KEY));
        }
    } else {
        // with non-HA case
        if (!OmUtils.isServiceIdsDefined(ozoneConf)) {
            return OzoneClientFactory.getRpcClient(ozoneConf);
        } else {
            throw new IOException("OzoneToken with no service ID can't " + "be renewed or canceled with local OM HA setup because we " + "don't know if the token is issued from local OM HA cluster " + "or not.");
        }
    }
}
Also used : ByteArrayInputStream(java.io.ByteArrayInputStream) OzoneTokenIdentifier(org.apache.hadoop.ozone.security.OzoneTokenIdentifier) OzoneConfiguration(org.apache.hadoop.hdds.conf.OzoneConfiguration) IOException(java.io.IOException) DataInputStream(java.io.DataInputStream)

Example 2 with OzoneTokenIdentifier

use of org.apache.hadoop.ozone.security.OzoneTokenIdentifier in project ozone by apache.

the class OzoneManager method cancelDelegationToken.

/**
 * Cancels a delegation token.
 *
 * @param token token to cancel
 * @throws IOException on error
 */
@Override
public void cancelDelegationToken(Token<OzoneTokenIdentifier> token) throws OMException {
    OzoneTokenIdentifier id = null;
    try {
        String canceller = getRemoteUser().getUserName();
        id = delegationTokenMgr.cancelToken(token, canceller);
        LOG.trace("Delegation token cancelled for dt: {}", id);
    } catch (OMException oex) {
        throw oex;
    } catch (IOException ex) {
        LOG.error("Delegation token cancellation failed for dt id: {}, cause: {}", id, ex.getMessage());
        throw new OMException("Delegation token renewal failed for dt: " + token, ex, TOKEN_ERROR_OTHER);
    }
}
Also used : OzoneTokenIdentifier(org.apache.hadoop.ozone.security.OzoneTokenIdentifier) CertificateSignRequest.getEncodedString(org.apache.hadoop.hdds.security.x509.certificates.utils.CertificateSignRequest.getEncodedString) IOException(java.io.IOException) UncheckedIOException(java.io.UncheckedIOException) OMException(org.apache.hadoop.ozone.om.exceptions.OMException)

Example 3 with OzoneTokenIdentifier

use of org.apache.hadoop.ozone.security.OzoneTokenIdentifier in project ozone by apache.

the class TestSecureOzoneCluster method testDelegationTokenRenewal.

/**
 * Tests delegation token renewal.
 */
@Test
public void testDelegationTokenRenewal() throws Exception {
    GenericTestUtils.setLogLevel(LoggerFactory.getLogger(Server.class.getName()), INFO);
    LogCapturer omLogs = LogCapturer.captureLogs(OzoneManager.getLogger());
    // Setup secure OM for start.
    OzoneConfiguration newConf = new OzoneConfiguration(conf);
    int tokenMaxLifetime = 1000;
    newConf.setLong(DELEGATION_TOKEN_MAX_LIFETIME_KEY, tokenMaxLifetime);
    setupOm(newConf);
    OzoneManager.setTestSecureOmFlag(true);
    try {
        om.setCertClient(new CertificateClientTestImpl(conf));
        om.start();
        UserGroupInformation ugi = UserGroupInformation.getCurrentUser();
        // Get first OM client which will authenticate via Kerberos
        omClient = new OzoneManagerProtocolClientSideTranslatorPB(OmTransportFactory.create(conf, ugi, null), RandomStringUtils.randomAscii(5));
        // Since client is already connected get a delegation token
        Token<OzoneTokenIdentifier> token = omClient.getDelegationToken(new Text("om"));
        // Check if token is of right kind and renewer is running om instance
        assertNotNull(token);
        assertEquals("OzoneToken", token.getKind().toString());
        assertEquals(OmUtils.getOmRpcAddress(conf), token.getService().toString());
        // Renew delegation token
        long expiryTime = omClient.renewDelegationToken(token);
        assertTrue(expiryTime > 0);
        omLogs.clearOutput();
        // Test failure of delegation renewal
        // 1. When token maxExpiryTime exceeds
        Thread.sleep(tokenMaxLifetime);
        OMException ex = LambdaTestUtils.intercept(OMException.class, "TOKEN_EXPIRED", () -> omClient.renewDelegationToken(token));
        assertEquals(TOKEN_EXPIRED, ex.getResult());
        omLogs.clearOutput();
        // 2. When renewer doesn't match (implicitly covers when renewer is
        // null or empty )
        Token<OzoneTokenIdentifier> token2 = omClient.getDelegationToken(new Text("randomService"));
        assertNotNull(token2);
        LambdaTestUtils.intercept(OMException.class, "Delegation token renewal failed", () -> omClient.renewDelegationToken(token2));
        assertTrue(omLogs.getOutput().contains(" with non-matching " + "renewer randomService"));
        omLogs.clearOutput();
        // 3. Test tampered token
        OzoneTokenIdentifier tokenId = OzoneTokenIdentifier.readProtoBuf(token.getIdentifier());
        tokenId.setRenewer(new Text("om"));
        tokenId.setMaxDate(System.currentTimeMillis() * 2);
        Token<OzoneTokenIdentifier> tamperedToken = new Token<>(tokenId.getBytes(), token2.getPassword(), token2.getKind(), token2.getService());
        LambdaTestUtils.intercept(OMException.class, "Delegation token renewal failed", () -> omClient.renewDelegationToken(tamperedToken));
        assertTrue(omLogs.getOutput().contains("can't be found in " + "cache"));
        omLogs.clearOutput();
    } finally {
        om.stop();
        om.join();
    }
}
Also used : OzoneManagerProtocolClientSideTranslatorPB(org.apache.hadoop.ozone.om.protocolPB.OzoneManagerProtocolClientSideTranslatorPB) CertificateClientTestImpl(org.apache.hadoop.ozone.client.CertificateClientTestImpl) OzoneTokenIdentifier(org.apache.hadoop.ozone.security.OzoneTokenIdentifier) LogCapturer(org.apache.ozone.test.GenericTestUtils.LogCapturer) OzoneConfiguration(org.apache.hadoop.hdds.conf.OzoneConfiguration) Text(org.apache.hadoop.io.Text) Token(org.apache.hadoop.security.token.Token) OMException(org.apache.hadoop.ozone.om.exceptions.OMException) UserGroupInformation(org.apache.hadoop.security.UserGroupInformation) Test(org.junit.Test)

Example 4 with OzoneTokenIdentifier

use of org.apache.hadoop.ozone.security.OzoneTokenIdentifier in project ozone by apache.

the class TestDelegationToken method testDelegationToken.

/**
 * Performs following tests for delegation token.
 * 1. Get valid delegation token
 * 2. Test successful token renewal.
 * 3. Client can authenticate using token.
 * 4. Delegation token renewal without Kerberos auth fails.
 * 5. Test success of token cancellation.
 * 5. Test failure of token cancellation.
 */
@Test
public void testDelegationToken() throws Exception {
    // Capture logs for assertions
    LogCapturer logs = LogCapturer.captureLogs(Server.AUDITLOG);
    LogCapturer omLogs = LogCapturer.captureLogs(OzoneManager.getLogger());
    GenericTestUtils.setLogLevel(LoggerFactory.getLogger(Server.class.getName()), INFO);
    // Setup secure OM for start
    setupOm(conf);
    // These are two very important lines: ProtobufRpcEngine uses ClientCache
    // which caches clients until no more references. Cache key is the
    // SocketFactory which means that we use one Client instance for
    // all the Hadoop RPC.
    // 
    // Hadoop Client caches connections with a connection pool. Even if you
    // close the client here, if you have ANY Hadoop RPC clients which uses the
    // same Client, connections can be reused.
    // 
    // Here we closed all the OTHER Hadoop RPC clients to have only the clients
    // from this unit test.
    // 
    // With this approach all the following client.close() calls trigger a
    // Client.close (if there is no other open Hadoop RPC client) which triggers
    // connection close for all the available connection.
    // 
    // The following test tests the authorization of the new client calls, it
    // requires a real connection close and connection open as the authorization
    // is part the initial handhsake of Hadoop RPC.
    om.getScmClient().getBlockClient().close();
    om.getScmClient().getContainerClient().close();
    try {
        // Start OM
        om.setCertClient(new CertificateClientTestImpl(conf));
        om.start();
        UserGroupInformation ugi = UserGroupInformation.getCurrentUser();
        String username = ugi.getUserName();
        // Get first OM client which will authenticate via Kerberos
        omClient = new OzoneManagerProtocolClientSideTranslatorPB(OmTransportFactory.create(conf, ugi, null), RandomStringUtils.randomAscii(5));
        // Assert if auth was successful via Kerberos
        assertFalse(logs.getOutput().contains("Auth successful for " + username + " (auth:KERBEROS)"));
        // Case 1: Test successful delegation token.
        Token<OzoneTokenIdentifier> token = omClient.getDelegationToken(new Text("om"));
        // Case 2: Test successful token renewal.
        long renewalTime = omClient.renewDelegationToken(token);
        assertTrue(renewalTime > 0);
        // Check if token is of right kind and renewer is running om instance
        assertNotNull(token);
        assertEquals("OzoneToken", token.getKind().toString());
        assertEquals(OmUtils.getOmRpcAddress(conf), token.getService().toString());
        omClient.close();
        // Create a remote ugi and set its authentication method to Token
        UserGroupInformation testUser = UserGroupInformation.createRemoteUser(TEST_USER);
        testUser.addToken(token);
        testUser.setAuthenticationMethod(AuthMethod.TOKEN);
        UserGroupInformation.setLoginUser(testUser);
        // Get Om client, this time authentication should happen via Token
        testUser.doAs((PrivilegedExceptionAction<Void>) () -> {
            omClient = new OzoneManagerProtocolClientSideTranslatorPB(OmTransportFactory.create(conf, testUser, null), RandomStringUtils.randomAscii(5));
            return null;
        });
        // Case 3: Test Client can authenticate using token.
        assertFalse(logs.getOutput().contains("Auth successful for " + username + " (auth:TOKEN)"));
        OzoneTestUtils.expectOmException(VOLUME_NOT_FOUND, () -> omClient.deleteVolume("vol1"));
        assertTrue("Log file doesn't contain successful auth for user " + username, logs.getOutput().contains("Auth successful for " + username + " (auth:TOKEN)"));
        // Case 4: Test failure of token renewal.
        // Call to renewDelegationToken will fail but it will confirm that
        // initial connection via DT succeeded
        omLogs.clearOutput();
        OMException ex = LambdaTestUtils.intercept(OMException.class, "INVALID_AUTH_METHOD", () -> omClient.renewDelegationToken(token));
        assertEquals(INVALID_AUTH_METHOD, ex.getResult());
        assertTrue(logs.getOutput().contains("Auth successful for " + username + " (auth:TOKEN)"));
        omLogs.clearOutput();
        // testUser.setAuthenticationMethod(AuthMethod.KERBEROS);
        omClient.close();
        UserGroupInformation.setLoginUser(ugi);
        omClient = new OzoneManagerProtocolClientSideTranslatorPB(OmTransportFactory.create(conf, ugi, null), RandomStringUtils.randomAscii(5));
        // Case 5: Test success of token cancellation.
        omClient.cancelDelegationToken(token);
        omClient.close();
        // Wait for client to timeout
        Thread.sleep(CLIENT_TIMEOUT);
        assertFalse(logs.getOutput().contains("Auth failed for"));
        // Case 6: Test failure of token cancellation.
        // Get Om client, this time authentication using Token will fail as
        // token is not in cache anymore.
        omClient = new OzoneManagerProtocolClientSideTranslatorPB(OmTransportFactory.create(conf, testUser, null), RandomStringUtils.randomAscii(5));
        ex = LambdaTestUtils.intercept(OMException.class, "Cancel delegation token failed", () -> omClient.cancelDelegationToken(token));
        assertEquals(TOKEN_ERROR_OTHER, ex.getResult());
        assertTrue(logs.getOutput().contains("Auth failed for"));
    } finally {
        om.stop();
        om.join();
    }
}
Also used : OzoneManagerProtocolClientSideTranslatorPB(org.apache.hadoop.ozone.om.protocolPB.OzoneManagerProtocolClientSideTranslatorPB) CertificateClientTestImpl(org.apache.hadoop.ozone.client.CertificateClientTestImpl) OzoneTokenIdentifier(org.apache.hadoop.ozone.security.OzoneTokenIdentifier) LogCapturer(org.apache.ozone.test.GenericTestUtils.LogCapturer) Text(org.apache.hadoop.io.Text) OMException(org.apache.hadoop.ozone.om.exceptions.OMException) UserGroupInformation(org.apache.hadoop.security.UserGroupInformation) Test(org.junit.Test)

Example 5 with OzoneTokenIdentifier

use of org.apache.hadoop.ozone.security.OzoneTokenIdentifier in project ozone by apache.

the class OMCancelDelegationTokenRequest method validateAndUpdateCache.

@Override
public OMClientResponse validateAndUpdateCache(OzoneManager ozoneManager, long transactionLogIndex, OzoneManagerDoubleBufferHelper ozoneManagerDoubleBufferHelper) {
    OMMetadataManager omMetadataManager = ozoneManager.getMetadataManager();
    OMClientResponse omClientResponse = null;
    OMResponse.Builder omResponse = OmResponseUtil.getOMResponseBuilder(getOmRequest());
    OzoneTokenIdentifier ozoneTokenIdentifier = null;
    try {
        ozoneTokenIdentifier = OzoneTokenIdentifier.readProtoBuf(getToken().getIdentifier());
        // Remove token from in-memory.
        ozoneManager.getDelegationTokenMgr().removeToken(ozoneTokenIdentifier);
        // Update Cache.
        omMetadataManager.getDelegationTokenTable().addCacheEntry(new CacheKey<>(ozoneTokenIdentifier), new CacheValue<>(Optional.absent(), transactionLogIndex));
        omClientResponse = new OMCancelDelegationTokenResponse(ozoneTokenIdentifier, omResponse.setCancelDelegationTokenResponse(CancelDelegationTokenResponseProto.newBuilder().setResponse(SecurityProtos.CancelDelegationTokenResponseProto.newBuilder())).build());
    } catch (IOException ex) {
        LOG.error("Error in cancel DelegationToken {}", ozoneTokenIdentifier, ex);
        omClientResponse = new OMCancelDelegationTokenResponse(null, createErrorOMResponse(omResponse, ex));
    } finally {
        addResponseToDoubleBuffer(transactionLogIndex, omClientResponse, ozoneManagerDoubleBufferHelper);
    }
    if (LOG.isDebugEnabled()) {
        LOG.debug("Cancelled delegation token: {}", ozoneTokenIdentifier);
    }
    return omClientResponse;
}
Also used : OMCancelDelegationTokenResponse(org.apache.hadoop.ozone.om.response.security.OMCancelDelegationTokenResponse) OMClientResponse(org.apache.hadoop.ozone.om.response.OMClientResponse) OzoneTokenIdentifier(org.apache.hadoop.ozone.security.OzoneTokenIdentifier) OMMetadataManager(org.apache.hadoop.ozone.om.OMMetadataManager) IOException(java.io.IOException) OMResponse(org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.OMResponse)

Aggregations

OzoneTokenIdentifier (org.apache.hadoop.ozone.security.OzoneTokenIdentifier)14 IOException (java.io.IOException)7 Text (org.apache.hadoop.io.Text)7 OMException (org.apache.hadoop.ozone.om.exceptions.OMException)5 OMClientResponse (org.apache.hadoop.ozone.om.response.OMClientResponse)4 UncheckedIOException (java.io.UncheckedIOException)3 CertificateSignRequest.getEncodedString (org.apache.hadoop.hdds.security.x509.certificates.utils.CertificateSignRequest.getEncodedString)3 OMMetadataManager (org.apache.hadoop.ozone.om.OMMetadataManager)3 OMResponse (org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.OMResponse)3 UserGroupInformation (org.apache.hadoop.security.UserGroupInformation)3 Test (org.junit.Test)3 OzoneConfiguration (org.apache.hadoop.hdds.conf.OzoneConfiguration)2 CertificateClientTestImpl (org.apache.hadoop.ozone.client.CertificateClientTestImpl)2 OzoneManagerProtocolClientSideTranslatorPB (org.apache.hadoop.ozone.om.protocolPB.OzoneManagerProtocolClientSideTranslatorPB)2 OMRequest (org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.OMRequest)2 GetDelegationTokenRequestProto (org.apache.hadoop.ozone.security.proto.SecurityProtos.GetDelegationTokenRequestProto)2 Token (org.apache.hadoop.security.token.Token)2 LogCapturer (org.apache.ozone.test.GenericTestUtils.LogCapturer)2 ByteArrayInputStream (java.io.ByteArrayInputStream)1 DataInputStream (java.io.DataInputStream)1