Search in sources :

Example 61 with GSSManager

use of org.ietf.jgss.GSSManager in project apache-kafka-on-k8s by banzaicloud.

the class SaslServerAuthenticator method createSaslKerberosServer.

private SaslServer createSaslKerberosServer(final AuthCallbackHandler saslServerCallbackHandler, final Map<String, ?> configs, Subject subject) throws IOException {
    // server is using a JAAS-authenticated subject: determine service principal name and hostname from kafka server's subject.
    final String servicePrincipal = SaslClientAuthenticator.firstPrincipal(subject);
    KerberosName kerberosName;
    try {
        kerberosName = KerberosName.parse(servicePrincipal);
    } catch (IllegalArgumentException e) {
        throw new KafkaException("Principal has name with unexpected format " + servicePrincipal);
    }
    final String servicePrincipalName = kerberosName.serviceName();
    final String serviceHostname = kerberosName.hostName();
    LOG.debug("Creating SaslServer for {} with mechanism {}", kerberosName, saslMechanism);
    // As described in http://docs.oracle.com/javase/8/docs/technotes/guides/security/jgss/jgss-features.html:
    // "To enable Java GSS to delegate to the native GSS library and its list of native mechanisms,
    // set the system property "sun.security.jgss.native" to true"
    // "In addition, when performing operations as a particular Subject, for example, Subject.doAs(...)
    // or Subject.doAsPrivileged(...), the to-be-used GSSCredential should be added to Subject's
    // private credential set. Otherwise, the GSS operations will fail since no credential is found."
    boolean usingNativeJgss = Boolean.getBoolean("sun.security.jgss.native");
    if (usingNativeJgss) {
        try {
            GSSManager manager = GSSManager.getInstance();
            // This Oid is used to represent the Kerberos version 5 GSS-API mechanism. It is defined in
            // RFC 1964.
            Oid krb5Mechanism = new Oid("1.2.840.113554.1.2.2");
            GSSName gssName = manager.createName(servicePrincipalName + "@" + serviceHostname, GSSName.NT_HOSTBASED_SERVICE);
            GSSCredential cred = manager.createCredential(gssName, GSSContext.INDEFINITE_LIFETIME, krb5Mechanism, GSSCredential.ACCEPT_ONLY);
            subject.getPrivateCredentials().add(cred);
        } catch (GSSException ex) {
            LOG.warn("Cannot add private credential to subject; clients authentication may fail", ex);
        }
    }
    try {
        return Subject.doAs(subject, new PrivilegedExceptionAction<SaslServer>() {

            public SaslServer run() throws SaslException {
                return Sasl.createSaslServer(saslMechanism, servicePrincipalName, serviceHostname, configs, saslServerCallbackHandler);
            }
        });
    } catch (PrivilegedActionException e) {
        throw new SaslException("Kafka Server failed to create a SaslServer to interact with a client during session authentication", e.getCause());
    }
}
Also used : GSSName(org.ietf.jgss.GSSName) PrivilegedActionException(java.security.PrivilegedActionException) SaslServer(javax.security.sasl.SaslServer) KerberosName(org.apache.kafka.common.security.kerberos.KerberosName) Oid(org.ietf.jgss.Oid) SaslException(javax.security.sasl.SaslException) GSSException(org.ietf.jgss.GSSException) GSSCredential(org.ietf.jgss.GSSCredential) GSSManager(org.ietf.jgss.GSSManager) KafkaException(org.apache.kafka.common.KafkaException)

Example 62 with GSSManager

use of org.ietf.jgss.GSSManager in project kafka by apache.

the class SaslChannelBuilderTest method testNativeGssapiCredentials.

@Test
public void testNativeGssapiCredentials() throws Exception {
    System.setProperty(SaslChannelBuilder.GSS_NATIVE_PROP, "true");
    TestJaasConfig jaasConfig = new TestJaasConfig();
    jaasConfig.addEntry("jaasContext", TestGssapiLoginModule.class.getName(), new HashMap<>());
    JaasContext jaasContext = new JaasContext("jaasContext", JaasContext.Type.SERVER, jaasConfig, null);
    Map<String, JaasContext> jaasContexts = Collections.singletonMap("GSSAPI", jaasContext);
    GSSManager gssManager = Mockito.mock(GSSManager.class);
    GSSName gssName = Mockito.mock(GSSName.class);
    Mockito.when(gssManager.createName(Mockito.anyString(), Mockito.any())).thenAnswer(unused -> gssName);
    Oid oid = new Oid("1.2.840.113554.1.2.2");
    Mockito.when(gssManager.createCredential(gssName, GSSContext.INDEFINITE_LIFETIME, oid, GSSCredential.ACCEPT_ONLY)).thenAnswer(unused -> Mockito.mock(GSSCredential.class));
    SaslChannelBuilder channelBuilder1 = createGssapiChannelBuilder(jaasContexts, gssManager);
    assertEquals(1, channelBuilder1.subject("GSSAPI").getPrincipals().size());
    assertEquals(1, channelBuilder1.subject("GSSAPI").getPrivateCredentials().size());
    SaslChannelBuilder channelBuilder2 = createGssapiChannelBuilder(jaasContexts, gssManager);
    assertEquals(1, channelBuilder2.subject("GSSAPI").getPrincipals().size());
    assertEquals(1, channelBuilder2.subject("GSSAPI").getPrivateCredentials().size());
    assertSame(channelBuilder1.subject("GSSAPI"), channelBuilder2.subject("GSSAPI"));
    Mockito.verify(gssManager, Mockito.times(1)).createCredential(gssName, GSSContext.INDEFINITE_LIFETIME, oid, GSSCredential.ACCEPT_ONLY);
}
Also used : GSSName(org.ietf.jgss.GSSName) JaasContext(org.apache.kafka.common.security.JaasContext) GSSCredential(org.ietf.jgss.GSSCredential) GSSManager(org.ietf.jgss.GSSManager) Oid(org.ietf.jgss.Oid) TestJaasConfig(org.apache.kafka.common.security.authenticator.TestJaasConfig) Test(org.junit.jupiter.api.Test)

Example 63 with GSSManager

use of org.ietf.jgss.GSSManager in project kafka by apache.

the class SaslChannelBuilder method maybeAddNativeGssapiCredentials.

// As described in http://docs.oracle.com/javase/8/docs/technotes/guides/security/jgss/jgss-features.html:
// "To enable Java GSS to delegate to the native GSS library and its list of native mechanisms,
// set the system property "sun.security.jgss.native" to true"
// "In addition, when performing operations as a particular Subject, for example, Subject.doAs(...)
// or Subject.doAsPrivileged(...), the to-be-used GSSCredential should be added to Subject's
// private credential set. Otherwise, the GSS operations will fail since no credential is found."
private void maybeAddNativeGssapiCredentials(Subject subject) {
    boolean usingNativeJgss = Boolean.getBoolean(GSS_NATIVE_PROP);
    if (usingNativeJgss && subject.getPrivateCredentials(GSSCredential.class).isEmpty()) {
        final String servicePrincipal = SaslClientAuthenticator.firstPrincipal(subject);
        KerberosName kerberosName;
        try {
            kerberosName = KerberosName.parse(servicePrincipal);
        } catch (IllegalArgumentException e) {
            throw new KafkaException("Principal has name with unexpected format " + servicePrincipal);
        }
        final String servicePrincipalName = kerberosName.serviceName();
        final String serviceHostname = kerberosName.hostName();
        try {
            GSSManager manager = gssManager();
            // This Oid is used to represent the Kerberos version 5 GSS-API mechanism. It is defined in
            // RFC 1964.
            Oid krb5Mechanism = new Oid("1.2.840.113554.1.2.2");
            GSSName gssName = manager.createName(servicePrincipalName + "@" + serviceHostname, GSSName.NT_HOSTBASED_SERVICE);
            GSSCredential cred = manager.createCredential(gssName, GSSContext.INDEFINITE_LIFETIME, krb5Mechanism, GSSCredential.ACCEPT_ONLY);
            subject.getPrivateCredentials().add(cred);
            log.info("Configured native GSSAPI private credentials for {}@{}", serviceHostname, serviceHostname);
        } catch (GSSException ex) {
            log.warn("Cannot add private credential to subject; clients authentication may fail", ex);
        }
    }
}
Also used : GSSName(org.ietf.jgss.GSSName) GSSException(org.ietf.jgss.GSSException) GSSCredential(org.ietf.jgss.GSSCredential) GSSManager(org.ietf.jgss.GSSManager) KafkaException(org.apache.kafka.common.KafkaException) KerberosName(org.apache.kafka.common.security.kerberos.KerberosName) Oid(org.ietf.jgss.Oid)

Example 64 with GSSManager

use of org.ietf.jgss.GSSManager in project hbase by apache.

the class TestSpnegoHttpServer method testAllowedClient.

@Test
public void testAllowedClient() throws Exception {
    // Create the subject for the client
    final Subject clientSubject = JaasKrbUtil.loginUsingKeytab(CLIENT_PRINCIPAL, clientKeytab);
    final Set<Principal> clientPrincipals = clientSubject.getPrincipals();
    // Make sure the subject has a principal
    assertFalse(clientPrincipals.isEmpty());
    // Get a TGT for the subject (might have many, different encryption types). The first should
    // be the default encryption type.
    Set<KerberosTicket> privateCredentials = clientSubject.getPrivateCredentials(KerberosTicket.class);
    assertFalse(privateCredentials.isEmpty());
    KerberosTicket tgt = privateCredentials.iterator().next();
    assertNotNull(tgt);
    // The name of the principal
    final String principalName = clientPrincipals.iterator().next().getName();
    // Run this code, logged in as the subject (the client)
    HttpResponse resp = Subject.doAs(clientSubject, new PrivilegedExceptionAction<HttpResponse>() {

        @Override
        public HttpResponse run() throws Exception {
            // Logs in with Kerberos via GSS
            GSSManager gssManager = GSSManager.getInstance();
            // jGSS Kerberos login constant
            Oid oid = new Oid("1.2.840.113554.1.2.2");
            GSSName gssClient = gssManager.createName(principalName, GSSName.NT_USER_NAME);
            GSSCredential credential = gssManager.createCredential(gssClient, GSSCredential.DEFAULT_LIFETIME, oid, GSSCredential.INITIATE_ONLY);
            HttpClientContext context = HttpClientContext.create();
            Lookup<AuthSchemeProvider> authRegistry = RegistryBuilder.<AuthSchemeProvider>create().register(AuthSchemes.SPNEGO, new SPNegoSchemeFactory(true, true)).build();
            HttpClient client = HttpClients.custom().setDefaultAuthSchemeRegistry(authRegistry).build();
            BasicCredentialsProvider credentialsProvider = new BasicCredentialsProvider();
            credentialsProvider.setCredentials(AuthScope.ANY, new KerberosCredentials(credential));
            URL url = new URL(getServerURL(server), "/echo?a=b");
            context.setTargetHost(new HttpHost(url.getHost(), url.getPort()));
            context.setCredentialsProvider(credentialsProvider);
            context.setAuthSchemeRegistry(authRegistry);
            HttpGet get = new HttpGet(url.toURI());
            return client.execute(get, context);
        }
    });
    assertNotNull(resp);
    assertEquals(HttpURLConnection.HTTP_OK, resp.getStatusLine().getStatusCode());
    assertEquals("a:b", EntityUtils.toString(resp.getEntity()).trim());
}
Also used : GSSName(org.ietf.jgss.GSSName) BasicCredentialsProvider(org.apache.http.impl.client.BasicCredentialsProvider) KerberosTicket(javax.security.auth.kerberos.KerberosTicket) HttpGet(org.apache.http.client.methods.HttpGet) KerberosCredentials(org.apache.http.auth.KerberosCredentials) HttpResponse(org.apache.http.HttpResponse) HttpClientContext(org.apache.http.client.protocol.HttpClientContext) Oid(org.ietf.jgss.Oid) SPNegoSchemeFactory(org.apache.http.impl.auth.SPNegoSchemeFactory) Subject(javax.security.auth.Subject) KrbException(org.apache.kerby.kerberos.kerb.KrbException) IOException(java.io.IOException) URL(java.net.URL) GSSCredential(org.ietf.jgss.GSSCredential) HttpHost(org.apache.http.HttpHost) GSSManager(org.ietf.jgss.GSSManager) HttpClient(org.apache.http.client.HttpClient) Lookup(org.apache.http.config.Lookup) Principal(java.security.Principal) Test(org.junit.Test)

Example 65 with GSSManager

use of org.ietf.jgss.GSSManager in project druid by druid-io.

the class DruidKerberosUtil method kerberosChallenge.

/**
 * This method always needs to be called within a doAs block so that the client's TGT credentials
 * can be read from the Subject.
 *
 * @return Kerberos Challenge String
 *
 * @throws Exception
 */
public static String kerberosChallenge(String server) throws AuthenticationException {
    kerberosLock.lock();
    try {
        // This Oid for Kerberos GSS-API mechanism.
        Oid mechOid = KerberosUtil.getOidInstance("GSS_KRB5_MECH_OID");
        GSSManager manager = GSSManager.getInstance();
        // GSS name for server
        GSSName serverName = manager.createName("HTTP@" + server, GSSName.NT_HOSTBASED_SERVICE);
        // Create a GSSContext for authentication with the service.
        // We're passing client credentials as null since we want them to be read from the Subject.
        GSSContext gssContext = manager.createContext(serverName.canonicalize(mechOid), mechOid, null, GSSContext.DEFAULT_LIFETIME);
        gssContext.requestMutualAuth(true);
        gssContext.requestCredDeleg(true);
        // Establish context
        byte[] inToken = new byte[0];
        byte[] outToken = gssContext.initSecContext(inToken, 0, inToken.length);
        gssContext.dispose();
        // Base64 encoded and stringified token for server
        return new String(StringUtils.encodeBase64(outToken), StandardCharsets.US_ASCII);
    } catch (GSSException | IllegalAccessException | NoSuchFieldException | ClassNotFoundException e) {
        throw new AuthenticationException(e);
    } finally {
        kerberosLock.unlock();
    }
}
Also used : GSSName(org.ietf.jgss.GSSName) GSSException(org.ietf.jgss.GSSException) AuthenticationException(org.apache.hadoop.security.authentication.client.AuthenticationException) GSSManager(org.ietf.jgss.GSSManager) GSSContext(org.ietf.jgss.GSSContext) Oid(org.ietf.jgss.Oid)

Aggregations

GSSManager (org.ietf.jgss.GSSManager)67 GSSName (org.ietf.jgss.GSSName)56 Oid (org.ietf.jgss.Oid)51 GSSContext (org.ietf.jgss.GSSContext)38 GSSCredential (org.ietf.jgss.GSSCredential)38 GSSException (org.ietf.jgss.GSSException)34 Subject (javax.security.auth.Subject)29 PrivilegedActionException (java.security.PrivilegedActionException)19 Principal (java.security.Principal)17 IOException (java.io.IOException)10 LoginContext (javax.security.auth.login.LoginContext)10 LoginException (javax.security.auth.login.LoginException)10 Test (org.junit.Test)9 KerberosTicket (javax.security.auth.kerberos.KerberosTicket)7 KerberosCredentials (org.apache.http.auth.KerberosCredentials)7 SaslException (javax.security.sasl.SaslException)6 PrivilegedExceptionAction (java.security.PrivilegedExceptionAction)5 KerberosPrincipal (javax.security.auth.kerberos.KerberosPrincipal)4 HttpServletRequest (javax.servlet.http.HttpServletRequest)4 HttpServletResponse (javax.servlet.http.HttpServletResponse)4