Search in sources :

Example 6 with GSSContext

use of org.ietf.jgss.GSSContext in project presto by prestodb.

the class SpnegoFilter method authenticate.

private Optional<Result> authenticate(String token) throws GSSException {
    GSSContext context = doAs(loginContext.getSubject(), () -> gssManager.createContext(serverCredential));
    try {
        byte[] inputToken = Base64.getDecoder().decode(token);
        byte[] outputToken = context.acceptSecContext(inputToken, 0, inputToken.length);
        // if it can't be set up in a single challenge-response cycle
        if (context.isEstablished()) {
            return Optional.of(new Result(Optional.ofNullable(outputToken), new KerberosPrincipal(context.getSrcName().toString())));
        }
        LOG.debug("Failed to establish GSS context for token %s", token);
    } catch (GSSException e) {
        // ignore and fail the authentication
        LOG.debug(e, "Authentication failed for token %s", token);
    } finally {
        try {
            context.dispose();
        } catch (GSSException e) {
        // ignore
        }
    }
    return Optional.empty();
}
Also used : KerberosPrincipal(javax.security.auth.kerberos.KerberosPrincipal) GSSException(org.ietf.jgss.GSSException) GSSContext(org.ietf.jgss.GSSContext)

Example 7 with GSSContext

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

the class TestKerberosAuthenticationHandler method testRequestWithAuthorization.

public void testRequestWithAuthorization() throws Exception {
    String token = KerberosTestUtils.doAsClient(new Callable<String>() {

        @Override
        public String call() throws Exception {
            GSSManager gssManager = GSSManager.getInstance();
            GSSContext gssContext = null;
            try {
                String servicePrincipal = KerberosTestUtils.getServerPrincipal();
                Oid oid = KerberosUtil.getOidInstance("NT_GSS_KRB5_PRINCIPAL");
                GSSName serviceName = gssManager.createName(servicePrincipal, oid);
                oid = KerberosUtil.getOidInstance("GSS_KRB5_MECH_OID");
                gssContext = gssManager.createContext(serviceName, oid, null, GSSContext.DEFAULT_LIFETIME);
                gssContext.requestCredDeleg(true);
                gssContext.requestMutualAuth(true);
                byte[] inToken = new byte[0];
                byte[] outToken = gssContext.initSecContext(inToken, 0, inToken.length);
                Base64 base64 = new Base64(0);
                return base64.encodeToString(outToken);
            } finally {
                if (gssContext != null) {
                    gssContext.dispose();
                }
            }
        }
    });
    HttpServletRequest request = Mockito.mock(HttpServletRequest.class);
    HttpServletResponse response = Mockito.mock(HttpServletResponse.class);
    Mockito.when(request.getHeader(KerberosAuthenticator.AUTHORIZATION)).thenReturn(KerberosAuthenticator.NEGOTIATE + " " + token);
    Mockito.when(request.getServerName()).thenReturn("localhost");
    AuthenticationToken authToken = handler.authenticate(request, response);
    if (authToken != null) {
        Mockito.verify(response).setHeader(Mockito.eq(KerberosAuthenticator.WWW_AUTHENTICATE), Mockito.matches(KerberosAuthenticator.NEGOTIATE + " .*"));
        Mockito.verify(response).setStatus(HttpServletResponse.SC_OK);
        Assert.assertEquals(KerberosTestUtils.getClientPrincipal(), authToken.getName());
        Assert.assertTrue(KerberosTestUtils.getClientPrincipal().startsWith(authToken.getUserName()));
        Assert.assertEquals(getExpectedType(), authToken.getType());
    } else {
        Mockito.verify(response).setHeader(Mockito.eq(KerberosAuthenticator.WWW_AUTHENTICATE), Mockito.matches(KerberosAuthenticator.NEGOTIATE + " .*"));
        Mockito.verify(response).setStatus(HttpServletResponse.SC_UNAUTHORIZED);
    }
}
Also used : HttpServletRequest(javax.servlet.http.HttpServletRequest) GSSName(org.ietf.jgss.GSSName) Base64(org.apache.commons.codec.binary.Base64) GSSManager(org.ietf.jgss.GSSManager) GSSContext(org.ietf.jgss.GSSContext) HttpServletResponse(javax.servlet.http.HttpServletResponse) Oid(org.ietf.jgss.Oid) AuthenticationException(org.apache.hadoop.security.authentication.client.AuthenticationException) ServletException(javax.servlet.ServletException)

Example 8 with GSSContext

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

the class DrillSpnegoLoginService method spnegoLogin.

private UserIdentity spnegoLogin(Object credentials) {
    String encodedAuthToken = (String) credentials;
    byte[] authToken = B64Code.decode(encodedAuthToken);
    GSSManager manager = GSSManager.getInstance();
    try {
        // Providing both OID's is required here. If we provide only one,
        // we're requiring that clients provide us the SPNEGO OID to authenticate via Kerberos.
        Oid[] knownOids = new Oid[2];
        // spnego
        knownOids[0] = new Oid("1.3.6.1.5.5.2");
        // kerberos
        knownOids[1] = new Oid("1.2.840.113554.1.2.2");
        GSSName gssName = manager.createName(spnegoConfig.getSpnegoPrincipal(), null);
        GSSCredential serverCreds = manager.createCredential(gssName, GSSCredential.INDEFINITE_LIFETIME, knownOids, GSSCredential.ACCEPT_ONLY);
        GSSContext gContext = manager.createContext(serverCreds);
        if (gContext == null) {
            logger.debug("SPNEGOUserRealm: failed to establish GSSContext");
        } else {
            while (!gContext.isEstablished()) {
                authToken = gContext.acceptSecContext(authToken, 0, authToken.length);
            }
            if (gContext.isEstablished()) {
                final String clientName = gContext.getSrcName().toString();
                final String realm = clientName.substring(clientName.indexOf(64) + 1);
                // Get the client user short name
                final String userShortName = new HadoopKerberosName(clientName).getShortName();
                logger.debug("Client Name: {}, realm: {} and shortName: {}", clientName, realm, userShortName);
                final SystemOptionManager sysOptions = drillContext.getOptionManager();
                final boolean isAdmin = ImpersonationUtil.hasAdminPrivileges(userShortName, ExecConstants.ADMIN_USERS_VALIDATOR.getAdminUsers(sysOptions), ExecConstants.ADMIN_USER_GROUPS_VALIDATOR.getAdminUserGroups(sysOptions));
                final Principal user = new DrillUserPrincipal(userShortName, isAdmin);
                final Subject subject = new Subject();
                subject.getPrincipals().add(user);
                if (isAdmin) {
                    return this._identityService.newUserIdentity(subject, user, DrillUserPrincipal.ADMIN_USER_ROLES);
                } else {
                    return this._identityService.newUserIdentity(subject, user, DrillUserPrincipal.NON_ADMIN_USER_ROLES);
                }
            }
        }
    } catch (GSSException gsse) {
        logger.warn("Caught GSSException trying to authenticate the client", gsse);
    } catch (IOException ex) {
        logger.warn("Caught IOException trying to get shortName of client user", ex);
    }
    return null;
}
Also used : GSSName(org.ietf.jgss.GSSName) HadoopKerberosName(org.apache.hadoop.security.HadoopKerberosName) SystemOptionManager(org.apache.drill.exec.server.options.SystemOptionManager) Oid(org.ietf.jgss.Oid) IOException(java.io.IOException) Subject(javax.security.auth.Subject) GSSException(org.ietf.jgss.GSSException) GSSCredential(org.ietf.jgss.GSSCredential) GSSManager(org.ietf.jgss.GSSManager) GSSContext(org.ietf.jgss.GSSContext) Principal(java.security.Principal)

Example 9 with GSSContext

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

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.
 * @throws Exception
 */
@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, new PrivilegedExceptionAction<String>() {

        @Override
        public String run() throws Exception {
            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) SecurityTest(org.apache.drill.categories.SecurityTest) Test(org.junit.Test)

Example 10 with GSSContext

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

the class TestSpnegoAuthentication method testDrillSpnegoLoginService.

/**
 * Validate successful {@link DrillSpnegoLoginService#login(String, Object)} when provided with client token for a
 * configured service principal.
 * @throws Exception
 */
@Test
public void testDrillSpnegoLoginService() throws Exception {
    // 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, new PrivilegedExceptionAction<String>() {

        @Override
        public String run() throws Exception {
            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();
                }
            }
        }
    });
    // Create a DrillbitContext with service principal and keytab for DrillSpnegoLoginService
    final DrillConfig newConfig = new DrillConfig(DrillConfig.create().withValue(ExecConstants.HTTP_AUTHENTICATION_MECHANISMS, ConfigValueFactory.fromIterable(Lists.newArrayList("spnego"))).withValue(ExecConstants.HTTP_SPNEGO_PRINCIPAL, ConfigValueFactory.fromAnyRef(spnegoHelper.SERVER_PRINCIPAL)).withValue(ExecConstants.HTTP_SPNEGO_KEYTAB, ConfigValueFactory.fromAnyRef(spnegoHelper.serverKeytab.toString())));
    final SystemOptionManager optionManager = Mockito.mock(SystemOptionManager.class);
    Mockito.when(optionManager.getOption(ExecConstants.ADMIN_USERS_VALIDATOR)).thenReturn(ExecConstants.ADMIN_USERS_VALIDATOR.DEFAULT_ADMIN_USERS);
    Mockito.when(optionManager.getOption(ExecConstants.ADMIN_USER_GROUPS_VALIDATOR)).thenReturn(ExecConstants.ADMIN_USER_GROUPS_VALIDATOR.DEFAULT_ADMIN_USER_GROUPS);
    final DrillbitContext drillbitContext = Mockito.mock(DrillbitContext.class);
    Mockito.when(drillbitContext.getConfig()).thenReturn(newConfig);
    Mockito.when(drillbitContext.getOptionManager()).thenReturn(optionManager);
    final DrillSpnegoLoginService loginService = new DrillSpnegoLoginService(drillbitContext);
    // Authenticate the client using its SPNEGO token
    final UserIdentity user = loginService.login(null, token);
    // Validate the UserIdentity of authenticated client
    assertTrue(user != null);
    assertTrue(user.getUserPrincipal().getName().equals(spnegoHelper.CLIENT_SHORT_NAME));
    assertTrue(user.isUserInRole("authenticated", null));
}
Also used : DrillbitContext(org.apache.drill.exec.server.DrillbitContext) GSSName(org.ietf.jgss.GSSName) SystemOptionManager(org.apache.drill.exec.server.options.SystemOptionManager) UserIdentity(org.eclipse.jetty.server.UserIdentity) Oid(org.ietf.jgss.Oid) DrillSpnegoLoginService(org.apache.drill.exec.server.rest.auth.DrillSpnegoLoginService) Subject(javax.security.auth.Subject) DrillbitStartupException(org.apache.drill.exec.exception.DrillbitStartupException) DrillConfig(org.apache.drill.common.config.DrillConfig) GSSManager(org.ietf.jgss.GSSManager) GSSContext(org.ietf.jgss.GSSContext) 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