Example usage for org.apache.hadoop.security UserGroupInformation hasKerberosCredentials

List of usage examples for org.apache.hadoop.security UserGroupInformation hasKerberosCredentials

Introduction

In this page you can find the example usage for org.apache.hadoop.security UserGroupInformation hasKerberosCredentials.

Prototype

public boolean hasKerberosCredentials() 

Source Link

Document

checks if logged in using kerberos

Usage

From source file:azkaban.jobtype.JavaJobRunnerMain.java

License:Apache License

private void runMethodAsProxyUser(Properties props, final Object obj, final String runMethod)
        throws IOException, InterruptedException {
    UserGroupInformation ugi = SecurityUtils.getProxiedUser(props, _logger, new Configuration());
    _logger.info("user " + ugi + " authenticationMethod " + ugi.getAuthenticationMethod());
    _logger.info("user " + ugi + " hasKerberosCredentials " + ugi.hasKerberosCredentials());
    SecurityUtils.getProxiedUser(props, _logger, new Configuration())
            .doAs(new PrivilegedExceptionAction<Void>() {
                @Override/*from  w  w w. j ava  2 s .c  o  m*/
                public Void run() throws Exception {
                    runMethod(obj, runMethod);
                    return null;
                }
            });
}

From source file:co.cask.cdap.security.impersonation.UGIProviderTest.java

License:Apache License

@Test
public void testDefaultUGIProvider() throws IOException {
    System.setProperty("sun.security.krb5.debug", "true");

    DefaultUGIProvider provider = new DefaultUGIProvider(cConf, locationFactory);

    // Try with local keytab file
    ImpersonationInfo aliceInfo = new ImpersonationInfo(getPrincipal("alice"), keytabFile.getAbsolutePath());
    UserGroupInformation aliceUGI = provider.getConfiguredUGI(aliceInfo);
    Assert.assertEquals(UserGroupInformation.AuthenticationMethod.KERBEROS, aliceUGI.getAuthenticationMethod());
    Assert.assertTrue(aliceUGI.hasKerberosCredentials());

    // Fetch it again, it is should return the same UGI since there is caching
    Assert.assertSame(aliceUGI, provider.getConfiguredUGI(aliceInfo));

    // Put the keytab on HDFS
    Location remoteKeytab = locationFactory.create("keytab").getTempFile(".tmp");
    Files.copy(keytabFile, Locations.newOutputSupplier(remoteKeytab));

    // Login with remote keytab file
    ImpersonationInfo bobInfo = new ImpersonationInfo(getPrincipal("bob"), remoteKeytab.toURI().toString());
    UserGroupInformation bobUGI = provider.getConfiguredUGI(bobInfo);
    Assert.assertEquals(UserGroupInformation.AuthenticationMethod.KERBEROS, bobUGI.getAuthenticationMethod());
    Assert.assertTrue(bobUGI.hasKerberosCredentials());

    // Delete the keytab on HDFS
    remoteKeytab.delete();/*w  w w. ja va 2  s. co  m*/

    // Fetch the bob UGI again, it should still return the valid one
    Assert.assertSame(bobUGI, provider.getConfiguredUGI(bobInfo));

    // Invalid the cache, getting of Alice UGI should pass, while getting of Bob should fails
    provider.invalidCache();
    Assert.assertNotSame(aliceUGI, provider.getConfiguredUGI(aliceInfo));
    try {
        provider.getConfiguredUGI(bobInfo);
        Assert.fail("Expected IOException when getting UGI for " + bobInfo);
    } catch (IOException e) {
        // Expected
    }
}

From source file:co.cask.cdap.security.impersonation.UGIProviderTest.java

License:Apache License

@Test
public void testRemoteUGIProvider() throws Exception {
    // Starts a mock server to handle remote UGI requests
    final NettyHttpService httpService = NettyHttpService.builder("remoteUGITest")
            .addHttpHandlers(Collections.singleton(new UGIProviderTestHandler())).build();

    httpService.startAndWait();//  w ww.j  a  v a 2s  . c  o m
    try {
        InMemoryDiscoveryService discoveryService = new InMemoryDiscoveryService();
        discoveryService
                .register(new Discoverable(Constants.Service.APP_FABRIC_HTTP, httpService.getBindAddress()));

        // Create Alice UGI
        RemoteUGIProvider ugiProvider = new RemoteUGIProvider(cConf, discoveryService, locationFactory);
        ImpersonationInfo aliceInfo = new ImpersonationInfo(getPrincipal("alice"),
                keytabFile.toURI().toString());
        UserGroupInformation aliceUGI = ugiProvider.getConfiguredUGI(aliceInfo);

        // Shouldn't be a kerberos UGI
        Assert.assertFalse(aliceUGI.hasKerberosCredentials());
        // Validate the credentials
        Token<? extends TokenIdentifier> token = aliceUGI.getCredentials().getToken(new Text("principal"));
        Assert.assertArrayEquals(aliceInfo.getPrincipal().getBytes(StandardCharsets.UTF_8),
                token.getIdentifier());
        Assert.assertArrayEquals(aliceInfo.getPrincipal().getBytes(StandardCharsets.UTF_8),
                token.getPassword());
        Assert.assertEquals(new Text("principal"), token.getKind());
        Assert.assertEquals(new Text("service"), token.getService());

        token = aliceUGI.getCredentials().getToken(new Text("keytab"));
        Assert.assertArrayEquals(aliceInfo.getKeytabURI().getBytes(StandardCharsets.UTF_8),
                token.getIdentifier());
        Assert.assertArrayEquals(aliceInfo.getKeytabURI().getBytes(StandardCharsets.UTF_8),
                token.getPassword());
        Assert.assertEquals(new Text("keytab"), token.getKind());
        Assert.assertEquals(new Text("service"), token.getService());

        // Fetch it again, it should return the same UGI due to caching
        Assert.assertSame(aliceUGI, ugiProvider.getConfiguredUGI(aliceInfo));

        // Invalid the cache and fetch it again. A different UGI should be returned
        ugiProvider.invalidCache();
        Assert.assertNotSame(aliceUGI, ugiProvider.getConfiguredUGI(aliceInfo));

    } finally {
        httpService.stopAndWait();
    }
}

From source file:org.apache.accumulo.core.cli.MapReduceClientOpts.java

License:Apache License

@Override
public AuthenticationToken getToken() {
    AuthenticationToken authToken = super.getToken();
    // For MapReduce, Kerberos credentials don't make it to the Mappers and Reducers,
    // 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 {/*from   w w w .  j a v a 2 s . c om*/
            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;
}

From source file:org.apache.accumulo.core.client.mapreduce.lib.impl.MapReduceClientOpts.java

License:Apache License

@Override
public AuthenticationToken getToken() {
    AuthenticationToken authToken = super.getToken();
    // For MapReduce, Kerberos credentials don't make it to the Mappers and Reducers,
    // 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 {//from   w  ww. j a  v  a2 s .  com
            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 = Connector.builder().usingClientInfo(getClientInfo())
                    .usingToken(newPrincipal, krbToken).build();

            // 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;
}

From source file:org.apache.accumulo.core.client.security.tokens.KerberosToken.java

License:Apache License

/**
 * Creates a token using the provided principal and the currently logged-in user via {@link UserGroupInformation}.
 *
 * @param principal//from   w  w w  . j  ava2 s  . com
 *          The user that is logged in
 */
public KerberosToken(String principal) throws IOException {
    requireNonNull(principal);
    final UserGroupInformation ugi = UserGroupInformation.getCurrentUser();
    checkArgument(ugi.hasKerberosCredentials(), "Subject is not logged in via Kerberos");
    checkArgument(principal.equals(ugi.getUserName()),
            "Provided principal does not match currently logged-in user");
    this.principal = ugi.getUserName();
}

From source file:org.apache.accumulo.core.clientImpl.mapreduce.lib.MapReduceClientOpts.java

License:Apache License

@Override
public AuthenticationToken getToken() {
    AuthenticationToken authToken = super.getToken();
    // For MapReduce, Kerberos credentials don't make it to the Mappers and Reducers,
    // 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 {//from w  ww  .ja  va2 s  .c  o  m
            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);
            try (AccumuloClient client = Accumulo.newClient().from(getClientProperties())
                    .as(newPrincipal, krbToken).build()) {

                // Do the explicit check to see if the user has the permission to get a delegation token
                if (!client.securityOperations().hasSystemPermission(client.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(
                            client.whoami() + " does not have permission to obtain a delegation token");
                }
                // Get the delegation token from Accumulo
                return client.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;
}

From source file:org.apache.accumulo.core.rpc.ThriftUtil.java

License:Apache License

/**
 * Some wonderful snippets of documentation from HBase on performing the re-login client-side (as well as server-side) in the following paragraph. We want to
 * attempt a re-login to automatically refresh the client's Krb "credentials" (remember, a server might also be a client, master sending RPC to tserver), but
 * we have to take care to avoid Kerberos' replay attack protection.
 * <p>/* w w w  . j  av  a  2  s  .  c  o m*/
 * If multiple clients with the same principal try to connect to the same server at the same time, the server assumes a replay attack is in progress. This is
 * a feature of kerberos. In order to work around this, what is done is that the client backs off randomly and tries to initiate the connection again. The
 * other problem is to do with ticket expiry. To handle that, a relogin is attempted.
 */
static void attemptClientReLogin() {
    try {
        UserGroupInformation loginUser = UserGroupInformation.getLoginUser();
        if (null == loginUser || !loginUser.hasKerberosCredentials()) {
            // We should have already checked that we're logged in and have credentials. A precondition-like check.
            throw new RuntimeException("Expected to find Kerberos UGI credentials, but did not");
        }
        UserGroupInformation currentUser = UserGroupInformation.getCurrentUser();
        // A Proxy user is the "effective user" (in name only), riding on top of the "real user"'s Krb credentials.
        UserGroupInformation realUser = currentUser.getRealUser();

        // re-login only in case it is the login user or superuser.
        if (loginUser.equals(currentUser) || loginUser.equals(realUser)) {
            if (UserGroupInformation.isLoginKeytabBased()) {
                log.info("Performing keytab-based Kerberos re-login");
                loginUser.reloginFromKeytab();
            } else {
                log.info("Performing ticket-cache-based Kerberos re-login");
                loginUser.reloginFromTicketCache();
            }

            // Avoid the replay attack protection, sleep 1 to 5000ms
            try {
                Thread.sleep((SASL_BACKOFF_RAND.nextInt(RELOGIN_MAX_BACKOFF) + 1));
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                return;
            }
        } else {
            log.debug("Not attempting Kerberos re-login: loginUser={}, currentUser={}, realUser={}", loginUser,
                    currentUser, realUser);
        }
    } catch (IOException e) {
        // The inability to check is worrisome and deserves a RuntimeException instead of a propagated IO-like Exception.
        log.warn("Failed to check (and/or perform) Kerberos client re-login", e);
        throw new RuntimeException(e);
    }
}

From source file:org.apache.accumulo.examples.cli.MapReduceClientOpts.java

License:Apache License

@Override
public AuthenticationToken getToken() {
    AuthenticationToken authToken = super.getToken();
    // For MapReduce, Kerberos credentials don't make it to the Mappers and Reducers,
    // so we need to request a delegation token and use that instead.
    if (authToken instanceof KerberosToken) {
        log.info("Received KerberosToken, fetching DelegationToken for MapReduce");

        try {// w ww. j  a  v a2  s. c  o  m
            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);

            Connector conn = getConnector();

            // 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;
}

From source file:org.apache.accumulo.hadoopImpl.mapreduce.lib.MapReduceClientOpts.java

License:Apache License

public Properties getClientProps() {
    Properties props = super.getClientProps();
    // For MapReduce, Kerberos credentials don't make it to the Mappers and Reducers,
    // so we need to request a delegation token and use that instead.
    AuthenticationToken authToken = ClientProperty.getAuthenticationToken(props);
    if (authToken instanceof KerberosToken) {
        log.info("Received KerberosToken, fetching DelegationToken for MapReduce");
        final KerberosToken krbToken = (KerberosToken) authToken;

        try {/*from  w  w w .j  av a 2s.c  o m*/
            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);

            try (AccumuloClient client = Accumulo.newClient().from(props).as(newPrincipal, krbToken).build()) {

                // Do the explicit check to see if the user has the permission to get a delegation token
                if (!client.securityOperations().hasSystemPermission(client.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(
                            client.whoami() + " does not have permission to obtain a delegation token");
                }

                // Get the delegation token from Accumulo
                AuthenticationToken token = client.securityOperations()
                        .getDelegationToken(new DelegationTokenConfig());

                props.setProperty(ClientProperty.AUTH_PRINCIPAL.getKey(), newPrincipal);
                ClientProperty.setAuthenticationToken(props, token);
            }
        } catch (IOException | AccumuloException | AccumuloSecurityException e) {
            final String msg = "Failed to acquire DelegationToken for use with MapReduce";
            log.error(msg, e);
            throw new RuntimeException(msg, e);
        }
    }
    return props;
}