Search in sources :

Example 36 with GSSContext

use of org.ietf.jgss.GSSContext in project airlift by airlift.

the class SpnegoAuthentication method authenticate.

@Override
public Result authenticate(Request request, ContentResponse response, HeaderInfo headerInfo, Attributes attributes) {
    URI normalizedUri = UriUtil.normalizedUri(request.getURI());
    return new Result() {

        @Override
        public URI getURI() {
            return normalizedUri;
        }

        @Override
        public void apply(Request request) {
            GSSContext context = null;
            try {
                String servicePrincipal = makeServicePrincipal(remoteServiceName, normalizedUri.getHost(), useCanonicalHostname);
                Session session = getSession();
                context = doAs(session.getLoginContext().getSubject(), () -> {
                    GSSContext result = GSS_MANAGER.createContext(GSS_MANAGER.createName(servicePrincipal, NT_HOSTBASED_SERVICE), SPNEGO_OID, session.getClientCredential(), INDEFINITE_LIFETIME);
                    result.requestMutualAuth(true);
                    result.requestConf(true);
                    result.requestInteg(true);
                    result.requestCredDeleg(false);
                    return result;
                });
                byte[] token = context.initSecContext(new byte[0], 0, 0);
                if (token != null) {
                    request.header(headerInfo.getHeader(), format("%s %s", NEGOTIATE, Base64.getEncoder().encodeToString(token)));
                } else {
                    throw new RuntimeException(format("No token generated from GSS context for %s", request.getURI()));
                }
            } catch (GSSException e) {
                throw new RuntimeException(format("Failed to establish GSSContext for request %s", request.getURI()), e);
            } catch (LoginException e) {
                throw new RuntimeException(format("Failed to establish LoginContext for request %s", request.getURI()), e);
            } finally {
                try {
                    if (context != null) {
                        context.dispose();
                    }
                } catch (GSSException e) {
                // ignore
                }
            }
        }
    };
}
Also used : GSSException(org.ietf.jgss.GSSException) GSSContext(org.ietf.jgss.GSSContext) Request(org.eclipse.jetty.client.api.Request) LoginException(javax.security.auth.login.LoginException) URI(java.net.URI)

Example 37 with GSSContext

use of org.ietf.jgss.GSSContext in project registry by hortonworks.

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) ServletException(javax.servlet.ServletException) AuthenticationException(com.hortonworks.registries.auth.client.AuthenticationException)

Example 38 with GSSContext

use of org.ietf.jgss.GSSContext in project registry by hortonworks.

the class KerberosAuthenticator method doSpnegoSequence.

/**
 * Implements the SPNEGO authentication sequence interaction using the current default principal
 * in the Kerberos cache (normally set via kinit).
 *
 * @param token the authentication token being used for the user.
 *
 * @throws IOException if an IO error occurred.
 * @throws AuthenticationException if an authentication error occurred.
 */
private void doSpnegoSequence(AuthenticatedURL.Token token) throws IOException, AuthenticationException {
    try {
        AccessControlContext context = AccessController.getContext();
        Subject subject = Subject.getSubject(context);
        if (subject == null || (subject.getPrivateCredentials(KerberosKey.class).isEmpty() && subject.getPrivateCredentials(KerberosTicket.class).isEmpty())) {
            LOG.debug("No subject in context, logging in");
            subject = new Subject();
            LoginContext login = new LoginContext("", subject, null, new KerberosConfiguration());
            login.login();
        }
        if (LOG.isDebugEnabled()) {
            LOG.debug("Using subject: " + subject);
        }
        Subject.doAs(subject, new PrivilegedExceptionAction<Void>() {

            @Override
            public Void run() throws Exception {
                GSSContext gssContext = null;
                try {
                    GSSManager gssManager = GSSManager.getInstance();
                    String servicePrincipal = KerberosUtil.getServicePrincipal("HTTP", KerberosAuthenticator.this.url.getHost());
                    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;
                    boolean established = false;
                    // Loop while the context is still not established
                    while (!established) {
                        outToken = gssContext.initSecContext(inToken, 0, inToken.length);
                        if (outToken != null) {
                            sendToken(outToken);
                        }
                        if (!gssContext.isEstablished()) {
                            inToken = readToken();
                        } else {
                            established = true;
                        }
                    }
                } finally {
                    if (gssContext != null) {
                        gssContext.dispose();
                    }
                }
                return null;
            }
        });
    } catch (PrivilegedActionException ex) {
        throw new AuthenticationException(ex.getException());
    } catch (LoginException ex) {
        throw new AuthenticationException(ex);
    }
    AuthenticatedURL.extractToken(conn, token);
}
Also used : GSSName(org.ietf.jgss.GSSName) PrivilegedActionException(java.security.PrivilegedActionException) Oid(org.ietf.jgss.Oid) Subject(javax.security.auth.Subject) LoginException(javax.security.auth.login.LoginException) PrivilegedActionException(java.security.PrivilegedActionException) IOException(java.io.IOException) LoginContext(javax.security.auth.login.LoginContext) AccessControlContext(java.security.AccessControlContext) GSSContext(org.ietf.jgss.GSSContext) GSSManager(org.ietf.jgss.GSSManager) LoginException(javax.security.auth.login.LoginException)

Example 39 with GSSContext

use of org.ietf.jgss.GSSContext in project polymap4-core by Polymap4.

the class SpnegoAuthenticator method doSpnegoAuth.

/**
 * Performs authentication using the SPNEGO mechanism.
 *
 * <p>
 * Returns null if authentication failed or if the provided
 * the auth scheme did not contain the SPNEGO/GSS token.
 * </p>
 *
 * @return SpnegoPrincipal for the given auth scheme.
 */
private SpnegoPrincipal doSpnegoAuth(final SpnegoAuthScheme scheme, final SpnegoHttpServletResponse resp) throws GSSException, IOException {
    final String principal;
    final byte[] gss = scheme.getToken();
    if (0 == gss.length) {
        LOGGER.finer("GSS data was NULL.");
        return null;
    }
    GSSContext context = null;
    GSSCredential delegCred = null;
    try {
        byte[] token = null;
        SpnegoAuthenticator.LOCK.lock();
        try {
            context = SpnegoAuthenticator.MANAGER.createContext(this.serverCredentials);
            token = context.acceptSecContext(gss, 0, gss.length);
        } finally {
            SpnegoAuthenticator.LOCK.unlock();
        }
        if (null == token) {
            LOGGER.finer("Token was NULL.");
            return null;
        }
        resp.setHeader(Constants.AUTHN_HEADER, Constants.NEGOTIATE_HEADER + ' ' + Base64.encode(token));
        if (!context.isEstablished()) {
            LOGGER.fine("context not established");
            resp.setStatus(HttpServletResponse.SC_UNAUTHORIZED, true);
            return null;
        }
        principal = context.getSrcName().toString();
        if (this.allowDelegation && context.getCredDelegState()) {
            delegCred = context.getDelegCred();
        }
    } finally {
        if (null != context) {
            SpnegoAuthenticator.LOCK.lock();
            try {
                context.dispose();
            } finally {
                SpnegoAuthenticator.LOCK.unlock();
            }
        }
    }
    return new SpnegoPrincipal(principal, KerberosPrincipal.KRB_NT_PRINCIPAL, delegCred);
}
Also used : GSSCredential(org.ietf.jgss.GSSCredential) GSSContext(org.ietf.jgss.GSSContext)

Example 40 with GSSContext

use of org.ietf.jgss.GSSContext in project polymap4-core by Polymap4.

the class SpnegoHttpURLConnection method connect.

/**
 * Opens a communications link to the resource referenced by
 * this URL, if such a connection has not already been established.
 *
 * @param url
 * @param dooutput optional message/payload to send to server
 * @return an HttpURLConnection object
 * @throws GSSException
 * @throws PrivilegedActionException
 * @throws IOException
 * @throws LoginException
 *
 * @see java.net.URLConnection#connect()
 */
public HttpURLConnection connect(final URL url, final ByteArrayOutputStream dooutput) throws GSSException, PrivilegedActionException, IOException {
    assertNotConnected();
    GSSContext context = null;
    try {
        byte[] data = null;
        SpnegoHttpURLConnection.LOCK.lock();
        try {
            // work-around to GSSContext/AD timestamp vs sequence field replay bug
            try {
                Thread.sleep(31);
            } catch (InterruptedException e) {
                assert true;
            }
            context = this.getGSSContext(url);
            context.requestMutualAuth(true);
            context.requestConf(true);
            context.requestInteg(true);
            context.requestReplayDet(true);
            context.requestSequenceDet(true);
            context.requestCredDeleg(this.reqCredDeleg);
            data = context.initSecContext(EMPTY_BYTE, 0, 0);
        } finally {
            SpnegoHttpURLConnection.LOCK.unlock();
        }
        this.conn = (HttpURLConnection) url.openConnection();
        this.connected = true;
        final Set<String> keys = this.requestProperties.keySet();
        for (final String key : keys) {
            for (String value : this.requestProperties.get(key)) {
                this.conn.addRequestProperty(key, value);
            }
        }
        // TODO : re-factor to support (302) redirects
        this.conn.setInstanceFollowRedirects(false);
        this.conn.setRequestMethod(this.requestMethod);
        this.conn.setRequestProperty(Constants.AUTHZ_HEADER, Constants.NEGOTIATE_HEADER + ' ' + Base64.encode(data));
        if (null != dooutput && dooutput.size() > 0) {
            this.conn.setDoOutput(true);
            dooutput.writeTo(this.conn.getOutputStream());
        }
        this.conn.connect();
        final SpnegoAuthScheme scheme = SpnegoProvider.getAuthScheme(this.conn.getHeaderField(Constants.AUTHN_HEADER));
        // app servers will not return a WWW-Authenticate on 302, (and 30x...?)
        if (null == scheme) {
            LOGGER.fine("SpnegoProvider.getAuthScheme(...) returned null.");
        } else {
            data = scheme.getToken();
            if (Constants.NEGOTIATE_HEADER.equalsIgnoreCase(scheme.getScheme())) {
                SpnegoHttpURLConnection.LOCK.lock();
                try {
                    data = context.initSecContext(data, 0, data.length);
                } finally {
                    SpnegoHttpURLConnection.LOCK.unlock();
                }
                // TODO : support context loops where i>1
                if (null != data) {
                    LOGGER.warning("Server requested context loop: " + data.length);
                }
            } else {
                throw new UnsupportedOperationException("Scheme NOT Supported: " + scheme.getScheme());
            }
            this.cntxtEstablished = context.isEstablished();
        }
    } finally {
        this.dispose(context);
    }
    return this.conn;
}
Also used : GSSContext(org.ietf.jgss.GSSContext)

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