Search in sources :

Example 41 with GSSContext

use of org.ietf.jgss.GSSContext in project async-http-client by AsyncHttpClient.

the class SpnegoEngine method generateToken.

public String generateToken(String server) throws SpnegoEngineException {
    GSSContext gssContext = null;
    // base64 decoded challenge
    byte[] token = null;
    Oid negotiationOid;
    try {
        log.debug("init {}", server);
        /*
       * Using the SPNEGO OID is the correct method. Kerberos v5 works for IIS but not JBoss. Unwrapping the initial token when using SPNEGO OID looks like what is described
       * here...
       *
       * http://msdn.microsoft.com/en-us/library/ms995330.aspx
       *
       * Another helpful URL...
       *
       * http://publib.boulder.ibm.com/infocenter/wasinfo/v7r0/index.jsp?topic=/com.ibm.websphere.express.doc/info/exp/ae/tsec_SPNEGO_token.html
       *
       * Unfortunately SPNEGO is JRE >=1.6.
       */
        // Try SPNEGO by default, fall back to Kerberos later if error
        negotiationOid = new Oid(SPNEGO_OID);
        boolean tryKerberos = false;
        try {
            GSSManager manager = GSSManager.getInstance();
            GSSName serverName = manager.createName("HTTP@" + server, GSSName.NT_HOSTBASED_SERVICE);
            gssContext = manager.createContext(serverName.canonicalize(negotiationOid), negotiationOid, null, GSSContext.DEFAULT_LIFETIME);
            gssContext.requestMutualAuth(true);
            gssContext.requestCredDeleg(true);
        } catch (GSSException ex) {
            log.error("generateToken", ex);
            // Rethrow any other exception.
            if (ex.getMajor() == GSSException.BAD_MECH) {
                log.debug("GSSException BAD_MECH, retry with Kerberos MECH");
                tryKerberos = true;
            } else {
                throw ex;
            }
        }
        if (tryKerberos) {
            /* Kerberos v5 GSS-API mechanism defined in RFC 1964. */
            log.debug("Using Kerberos MECH {}", KERBEROS_OID);
            negotiationOid = new Oid(KERBEROS_OID);
            GSSManager manager = GSSManager.getInstance();
            GSSName serverName = manager.createName("HTTP@" + server, GSSName.NT_HOSTBASED_SERVICE);
            gssContext = manager.createContext(serverName.canonicalize(negotiationOid), negotiationOid, null, GSSContext.DEFAULT_LIFETIME);
            gssContext.requestMutualAuth(true);
            gssContext.requestCredDeleg(true);
        }
        // TODO suspicious: this will always be null because no value has been assigned before. Assign directly?
        if (token == null) {
            token = new byte[0];
        }
        token = gssContext.initSecContext(token, 0, token.length);
        if (token == null) {
            throw new SpnegoEngineException("GSS security context initialization failed");
        }
        /*
       * IIS accepts Kerberos and SPNEGO tokens. Some other servers Jboss, Glassfish? seem to only accept SPNEGO. Below wraps Kerberos into SPNEGO token.
       */
        if (spnegoGenerator != null && negotiationOid.toString().equals(KERBEROS_OID)) {
            token = spnegoGenerator.generateSpnegoDERObject(token);
        }
        gssContext.dispose();
        String tokenstr = Base64.getEncoder().encodeToString(token);
        log.debug("Sending response '{}' back to the server", tokenstr);
        return tokenstr;
    } catch (GSSException gsse) {
        log.error("generateToken", gsse);
        if (gsse.getMajor() == GSSException.DEFECTIVE_CREDENTIAL || gsse.getMajor() == GSSException.CREDENTIALS_EXPIRED)
            throw new SpnegoEngineException(gsse.getMessage(), gsse);
        if (gsse.getMajor() == GSSException.NO_CRED)
            throw new SpnegoEngineException(gsse.getMessage(), gsse);
        if (gsse.getMajor() == GSSException.DEFECTIVE_TOKEN || gsse.getMajor() == GSSException.DUPLICATE_TOKEN || gsse.getMajor() == GSSException.OLD_TOKEN)
            throw new SpnegoEngineException(gsse.getMessage(), gsse);
        // other error
        throw new SpnegoEngineException(gsse.getMessage());
    } catch (IOException ex) {
        throw new SpnegoEngineException(ex.getMessage());
    }
}
Also used : GSSName(org.ietf.jgss.GSSName) GSSException(org.ietf.jgss.GSSException) GSSContext(org.ietf.jgss.GSSContext) GSSManager(org.ietf.jgss.GSSManager) Oid(org.ietf.jgss.Oid) IOException(java.io.IOException)

Example 42 with GSSContext

use of org.ietf.jgss.GSSContext in project zeppelin by apache.

the class KerberosRealm method runWithPrincipal.

private AuthenticationToken runWithPrincipal(String serverPrincipal, byte[] clientToken, Base64 base64, HttpServletResponse response) throws IOException, GSSException {
    GSSContext gssContext = null;
    GSSCredential gssCreds = null;
    AuthenticationToken token = null;
    try {
        LOG.trace("SPNEGO initiated with server principal [{}]", serverPrincipal);
        gssCreds = this.gssManager.createCredential(this.gssManager.createName(serverPrincipal, KerberosUtil.NT_GSS_KRB5_PRINCIPAL_OID), GSSCredential.INDEFINITE_LIFETIME, new Oid[] { KerberosUtil.GSS_SPNEGO_MECH_OID, KerberosUtil.GSS_KRB5_MECH_OID }, GSSCredential.ACCEPT_ONLY);
        gssContext = this.gssManager.createContext(gssCreds);
        byte[] serverToken = gssContext.acceptSecContext(clientToken, 0, clientToken.length);
        if (serverToken != null && serverToken.length > 0) {
            String authenticate = base64.encodeToString(serverToken);
            response.setHeader(KerberosAuthenticator.WWW_AUTHENTICATE, KerberosAuthenticator.NEGOTIATE + " " + authenticate);
        }
        if (!gssContext.isEstablished()) {
            response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
            LOG.trace("SPNEGO in progress");
        } else {
            String clientPrincipal = gssContext.getSrcName().toString();
            KerberosName kerberosName = new KerberosName(clientPrincipal);
            String userName = kerberosName.getShortName();
            token = new AuthenticationToken(userName, clientPrincipal, TYPE);
            response.setStatus(HttpServletResponse.SC_OK);
            LOG.trace("SPNEGO completed for client principal [{}]", clientPrincipal);
        }
    } finally {
        if (gssContext != null) {
            gssContext.dispose();
        }
        if (gssCreds != null) {
            gssCreds.dispose();
        }
    }
    return token;
}
Also used : AuthenticationToken(org.apache.hadoop.security.authentication.server.AuthenticationToken) GSSCredential(org.ietf.jgss.GSSCredential) GSSContext(org.ietf.jgss.GSSContext) Oid(org.ietf.jgss.Oid)

Example 43 with GSSContext

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

the class DruidKerberosAuthenticationHandler method authenticate.

@Override
public AuthenticationToken authenticate(HttpServletRequest request, final HttpServletResponse response) throws IOException, AuthenticationException {
    AuthenticationToken token;
    String authorization = request.getHeader(org.apache.hadoop.security.authentication.client.KerberosAuthenticator.AUTHORIZATION);
    if (authorization == null || !authorization.startsWith(org.apache.hadoop.security.authentication.client.KerberosAuthenticator.NEGOTIATE)) {
        return null;
    } else {
        authorization = authorization.substring(org.apache.hadoop.security.authentication.client.KerberosAuthenticator.NEGOTIATE.length()).trim();
        final byte[] clientToken = StringUtils.decodeBase64String(authorization);
        final String serverName = request.getServerName();
        try {
            token = Subject.doAs(serverSubject, new PrivilegedExceptionAction<AuthenticationToken>() {

                @Override
                public AuthenticationToken run() throws Exception {
                    AuthenticationToken token = null;
                    GSSContext gssContext = null;
                    GSSCredential gssCreds = null;
                    try {
                        gssCreds = gssManager.createCredential(gssManager.createName(KerberosUtil.getServicePrincipal("HTTP", serverName), KerberosUtil.getOidInstance("NT_GSS_KRB5_PRINCIPAL")), GSSCredential.INDEFINITE_LIFETIME, new Oid[] { KerberosUtil.getOidInstance("GSS_SPNEGO_MECH_OID"), KerberosUtil.getOidInstance("GSS_KRB5_MECH_OID") }, GSSCredential.ACCEPT_ONLY);
                        gssContext = gssManager.createContext(gssCreds);
                        byte[] serverToken = gssContext.acceptSecContext(clientToken, 0, clientToken.length);
                        if (serverToken != null && serverToken.length > 0) {
                            String authenticate = StringUtils.encodeBase64String(serverToken);
                            response.setHeader(org.apache.hadoop.security.authentication.client.KerberosAuthenticator.WWW_AUTHENTICATE, org.apache.hadoop.security.authentication.client.KerberosAuthenticator.NEGOTIATE + " " + authenticate);
                        }
                        if (!gssContext.isEstablished()) {
                            response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
                            log.trace("SPNEGO in progress");
                        } else {
                            String clientPrincipal = gssContext.getSrcName().toString();
                            KerberosName kerberosName = new KerberosName(clientPrincipal);
                            String userName = kerberosName.getShortName();
                            token = new AuthenticationToken(userName, clientPrincipal, getType());
                            response.setStatus(HttpServletResponse.SC_OK);
                            log.trace("SPNEGO completed for principal [%s]", clientPrincipal);
                        }
                    } finally {
                        if (gssContext != null) {
                            gssContext.dispose();
                        }
                        if (gssCreds != null) {
                            gssCreds.dispose();
                        }
                    }
                    return token;
                }
            });
        } catch (PrivilegedActionException ex) {
            if (ex.getException() instanceof IOException) {
                throw (IOException) ex.getException();
            } else {
                throw new AuthenticationException(ex.getException());
            }
        }
    }
    return token;
}
Also used : AuthenticationToken(org.apache.hadoop.security.authentication.server.AuthenticationToken) GSSCredential(org.ietf.jgss.GSSCredential) PrivilegedActionException(java.security.PrivilegedActionException) AuthenticationException(org.apache.hadoop.security.authentication.client.AuthenticationException) GSSContext(org.ietf.jgss.GSSContext) PrivilegedExceptionAction(java.security.PrivilegedExceptionAction) Oid(org.ietf.jgss.Oid) KerberosName(org.apache.hadoop.security.authentication.util.KerberosName) IOException(java.io.IOException)

Example 44 with GSSContext

use of org.ietf.jgss.GSSContext 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)

Example 45 with GSSContext

use of org.ietf.jgss.GSSContext in project drill by apache.

the class TestDrillSpnegoAuthenticator method testSpnegoLoginInvalidToken.

/**
 * Test to verify authentication fails when client sends invalid SPNEGO token for the
 * {@link WebServerConstants#SPENGO_LOGIN_RESOURCE_PATH} resource.
 */
@Test
public void testSpnegoLoginInvalidToken() throws Exception {
    final HttpServletRequest request = Mockito.mock(HttpServletRequest.class);
    final HttpServletResponse response = Mockito.mock(HttpServletResponse.class);
    final HttpSession session = Mockito.mock(HttpSession.class);
    // Create client subject using it's principal and keytab
    final Subject clientSubject = JaasKrbUtil.loginUsingKeytab(spnegoHelper.CLIENT_PRINCIPAL, spnegoHelper.clientKeytab.getAbsoluteFile());
    // Generate a SPNEGO token for the peer SERVER_PRINCIPAL from this CLIENT_PRINCIPAL
    final String token = Subject.doAs(clientSubject, (PrivilegedExceptionAction<String>) () -> {
        final GSSManager gssManager = GSSManager.getInstance();
        GSSContext gssContext = null;
        try {
            final Oid oid = GSSUtil.GSS_SPNEGO_MECH_OID;
            final GSSName serviceName = gssManager.createName(spnegoHelper.SERVER_PRINCIPAL, GSSName.NT_USER_NAME, oid);
            gssContext = gssManager.createContext(serviceName, oid, null, GSSContext.DEFAULT_LIFETIME);
            gssContext.requestCredDeleg(true);
            gssContext.requestMutualAuth(true);
            byte[] outToken = new byte[0];
            outToken = gssContext.initSecContext(outToken, 0, outToken.length);
            return Base64.encodeBase64String(outToken);
        } finally {
            if (gssContext != null) {
                gssContext.dispose();
            }
        }
    });
    Mockito.when(request.getSession(true)).thenReturn(session);
    final String httpReqAuthHeader = String.format("%s:%s", HttpHeader.NEGOTIATE.asString(), String.format("%s%s", "1234", token));
    Mockito.when(request.getHeader(HttpHeader.AUTHORIZATION.asString())).thenReturn(httpReqAuthHeader);
    Mockito.when(request.getRequestURI()).thenReturn(WebServerConstants.SPENGO_LOGIN_RESOURCE_PATH);
    assertEquals(spnegoAuthenticator.validateRequest(request, response, false), Authentication.UNAUTHENTICATED);
    verify(session, never()).setAttribute(SessionAuthentication.__J_AUTHENTICATED, null);
    verify(response, never()).sendError(401);
    verify(response, never()).setHeader(HttpHeader.WWW_AUTHENTICATE.asString(), HttpHeader.NEGOTIATE.asString());
}
Also used : HttpServletRequest(javax.servlet.http.HttpServletRequest) GSSName(org.ietf.jgss.GSSName) HttpSession(javax.servlet.http.HttpSession) GSSManager(org.ietf.jgss.GSSManager) GSSContext(org.ietf.jgss.GSSContext) HttpServletResponse(javax.servlet.http.HttpServletResponse) Oid(org.ietf.jgss.Oid) Subject(javax.security.auth.Subject) BaseTest(org.apache.drill.test.BaseTest) SecurityTest(org.apache.drill.categories.SecurityTest) Test(org.junit.Test)

Aggregations

GSSContext (org.ietf.jgss.GSSContext)53 GSSManager (org.ietf.jgss.GSSManager)36 GSSName (org.ietf.jgss.GSSName)35 Oid (org.ietf.jgss.Oid)34 GSSException (org.ietf.jgss.GSSException)28 GSSCredential (org.ietf.jgss.GSSCredential)23 Subject (javax.security.auth.Subject)19 PrivilegedActionException (java.security.PrivilegedActionException)13 LoginException (javax.security.auth.login.LoginException)12 IOException (java.io.IOException)10 LoginContext (javax.security.auth.login.LoginContext)8 Principal (java.security.Principal)5 PrivilegedExceptionAction (java.security.PrivilegedExceptionAction)5 AuthenticationException (org.apache.hadoop.security.authentication.client.AuthenticationException)5 Test (org.junit.Test)5 HttpServletRequest (javax.servlet.http.HttpServletRequest)4 HttpServletResponse (javax.servlet.http.HttpServletResponse)4 SecurityTest (org.apache.drill.categories.SecurityTest)3 SystemOptionManager (org.apache.drill.exec.server.options.SystemOptionManager)3 AuthenticationException (com.hortonworks.registries.auth.client.AuthenticationException)2