Search in sources :

Example 21 with GSSContext

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

the class SpnegoMechTestCase method testSuccess.

@Test
public void testSuccess() throws Exception {
    final Krb5LoginConfiguration krb5Configuration = new Krb5LoginConfiguration(Utils.getLoginConfiguration());
    Configuration.setConfiguration(krb5Configuration);
    LoginContext lc = Utils.loginWithKerberos(krb5Configuration, "user1@WILDFLY.ORG", "password1");
    Subject.doAs(lc.getSubject(), (PrivilegedExceptionAction<Void>) () -> {
        try (CloseableHttpClient httpClient = HttpClients.createDefault()) {
            GSSManager manager = GSSManager.getInstance();
            GSSName acceptorName = manager.createName("HTTP@localhost", GSSName.NT_HOSTBASED_SERVICE);
            GSSCredential credential = manager.createCredential(null, GSSCredential.DEFAULT_LIFETIME, new Oid[] { KERBEROS_V5, SPNEGO }, GSSCredential.INITIATE_ONLY);
            GSSContext context = manager.createContext(acceptorName, KERBEROS_V5, credential, GSSContext.INDEFINITE_LIFETIME);
            URI uri = new URI(url.toExternalForm() + "role1");
            byte[] message = new byte[0];
            for (int i = 0; i < 5; i++) {
                // prevent infinite loop - max 5 continuations
                message = context.initSecContext(message, 0, message.length);
                HttpGet request = new HttpGet(uri);
                request.setHeader(HEADER_AUTHORIZATION, CHALLENGE_PREFIX + Base64.getEncoder().encodeToString(message));
                try (CloseableHttpResponse response = httpClient.execute(request)) {
                    int statusCode = response.getStatusLine().getStatusCode();
                    if (statusCode != SC_UNAUTHORIZED) {
                        assertEquals("Unexpected status code in HTTP response.", SC_OK, statusCode);
                        assertEquals("Unexpected content of HTTP response.", SimpleServlet.RESPONSE_BODY, EntityUtils.toString(response.getEntity()));
                        // test cached identity
                        HttpGet request2 = new HttpGet(uri);
                        try (CloseableHttpResponse response2 = httpClient.execute(request2)) {
                            int statusCode2 = response.getStatusLine().getStatusCode();
                            assertEquals("Unexpected status code in HTTP response.", SC_OK, statusCode2);
                            assertEquals("Unexpected content of HTTP response.", SimpleServlet.RESPONSE_BODY, EntityUtils.toString(response2.getEntity()));
                        }
                        return null;
                    }
                    String responseHeader = response.getFirstHeader(HEADER_WWW_AUTHENTICATE).getValue();
                    if (!responseHeader.startsWith(CHALLENGE_PREFIX))
                        Assert.fail("Invalid authenticate header");
                    message = Base64.getDecoder().decode(responseHeader.substring(CHALLENGE_PREFIX.length()));
                }
            }
            Assert.fail("Infinite unauthorized loop");
        }
        return null;
    });
}
Also used : CloseableHttpClient(org.apache.http.impl.client.CloseableHttpClient) GSSName(org.ietf.jgss.GSSName) HttpGet(org.apache.http.client.methods.HttpGet) Oid(org.ietf.jgss.Oid) URI(java.net.URI) Krb5LoginConfiguration(org.jboss.as.test.integration.security.common.Krb5LoginConfiguration) LoginContext(javax.security.auth.login.LoginContext) GSSCredential(org.ietf.jgss.GSSCredential) GSSManager(org.ietf.jgss.GSSManager) GSSContext(org.ietf.jgss.GSSContext) CloseableHttpResponse(org.apache.http.client.methods.CloseableHttpResponse) Test(org.junit.Test)

Example 22 with GSSContext

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

the class JBossNegotiateScheme method authenticate.

/**
 * Produces Negotiate authorization Header based on token created by processChallenge.
 *
 * @param credentials Never used be the Negotiate scheme but must be provided to satisfy common-httpclient API. Credentials
 *        from JAAS will be used instead.
 * @param request The request being authenticated
 *
 * @throws AuthenticationException if authorization string cannot be generated due to an authentication failure
 *
 * @return an Negotiate authorization Header
 */
@Override
public Header authenticate(final Credentials credentials, final HttpRequest request, final HttpContext context) throws AuthenticationException {
    if (request == null) {
        throw new IllegalArgumentException("HTTP request may not be null");
    }
    if (state == State.TOKEN_GENERATED) {
        // hack for auto redirects
        return new BasicHeader("X-dummy", "Token already generated");
    }
    if (state != State.CHALLENGE_RECEIVED) {
        throw new IllegalStateException("Negotiation authentication process has not been initiated");
    }
    try {
        String key = HttpCoreContext.HTTP_TARGET_HOST;
        HttpHost host = (HttpHost) context.getAttribute(key);
        if (host == null) {
            throw new AuthenticationException("Authentication host is not set " + "in the execution context");
        }
        String authServer;
        if (!this.stripPort && host.getPort() > 0) {
            authServer = host.toHostString();
        } else {
            authServer = host.getHostName();
        }
        if (LOGGER.isDebugEnabled()) {
            LOGGER.debug("init " + authServer);
        }
        final Oid negotiationOid = new Oid(SPNEGO_OID);
        final GSSManager manager = GSSManager.getInstance();
        final GSSName serverName = manager.createName("HTTP@" + authServer, GSSName.NT_HOSTBASED_SERVICE);
        final GSSContext gssContext = manager.createContext(serverName.canonicalize(negotiationOid), negotiationOid, null, DEFAULT_LIFETIME);
        gssContext.requestMutualAuth(true);
        gssContext.requestCredDeleg(true);
        if (token == null) {
            token = new byte[0];
        }
        token = gssContext.initSecContext(token, 0, token.length);
        if (token == null) {
            state = State.FAILED;
            throw new AuthenticationException("GSS security context initialization failed");
        }
        state = State.TOKEN_GENERATED;
        String tokenstr = new String(base64codec.encode(token), StandardCharsets.UTF_8);
        if (LOGGER.isDebugEnabled()) {
            LOGGER.debug("Sending response '" + tokenstr + "' back to the auth server");
        }
        CharArrayBuffer buffer = new CharArrayBuffer(32);
        if (isProxy()) {
            buffer.append(AUTH.PROXY_AUTH_RESP);
        } else {
            buffer.append(AUTH.WWW_AUTH_RESP);
        }
        buffer.append(": Negotiate ");
        buffer.append(tokenstr);
        return new BufferedHeader(buffer);
    } catch (GSSException gsse) {
        state = State.FAILED;
        if (gsse.getMajor() == GSSException.DEFECTIVE_CREDENTIAL || gsse.getMajor() == GSSException.CREDENTIALS_EXPIRED)
            throw new InvalidCredentialsException(gsse.getMessage(), gsse);
        if (gsse.getMajor() == GSSException.NO_CRED)
            throw new InvalidCredentialsException(gsse.getMessage(), gsse);
        if (gsse.getMajor() == GSSException.DEFECTIVE_TOKEN || gsse.getMajor() == GSSException.DUPLICATE_TOKEN || gsse.getMajor() == GSSException.OLD_TOKEN)
            throw new AuthenticationException(gsse.getMessage(), gsse);
        // other error
        throw new AuthenticationException(gsse.getMessage());
    }
}
Also used : GSSName(org.ietf.jgss.GSSName) AuthenticationException(org.apache.http.auth.AuthenticationException) BufferedHeader(org.apache.http.message.BufferedHeader) CharArrayBuffer(org.apache.http.util.CharArrayBuffer) Oid(org.ietf.jgss.Oid) GSSException(org.ietf.jgss.GSSException) InvalidCredentialsException(org.apache.http.auth.InvalidCredentialsException) HttpHost(org.apache.http.HttpHost) GSSManager(org.ietf.jgss.GSSManager) GSSContext(org.ietf.jgss.GSSContext) BasicHeader(org.apache.http.message.BasicHeader)

Example 23 with GSSContext

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

the class KerberosAuthenticationFilter method filter.

@Override
public void filter(ContainerRequestContext context) {
    List<String> authHeaders = messageContext.getHttpHeaders().getRequestHeader(HttpHeaders.AUTHORIZATION);
    if (authHeaders == null || authHeaders.size() != 1) {
        LOG.fine("No Authorization header is available");
        throw ExceptionUtils.toNotAuthorizedException(null, getFaultResponse());
    }
    String[] authPair = authHeaders.get(0).split(" ");
    if (authPair.length != 2 || !NEGOTIATE_SCHEME.equalsIgnoreCase(authPair[0])) {
        LOG.fine("Negotiate Authorization scheme is expected");
        throw ExceptionUtils.toNotAuthorizedException(null, getFaultResponse());
    }
    byte[] serviceTicket = getServiceTicket(authPair[1]);
    try {
        Subject serviceSubject = loginAndGetSubject();
        GSSContext gssContext = createGSSContext();
        Subject.doAs(serviceSubject, new ValidateServiceTicketAction(gssContext, serviceTicket));
        GSSName srcName = gssContext.getSrcName();
        if (srcName == null) {
            throw ExceptionUtils.toNotAuthorizedException(null, getFaultResponse());
        }
        String complexUserName = srcName.toString();
        String simpleUserName = complexUserName;
        int index = simpleUserName.lastIndexOf('@');
        if (index > 0) {
            simpleUserName = simpleUserName.substring(0, index);
        }
        Message m = JAXRSUtils.getCurrentMessage();
        m.put(SecurityContext.class, createSecurityContext(simpleUserName, complexUserName, gssContext));
        if (!gssContext.getCredDelegState()) {
            gssContext.dispose();
        }
    } catch (LoginException e) {
        LOG.fine("Unsuccessful JAAS login for the service principal: " + e.getMessage());
        throw ExceptionUtils.toNotAuthorizedException(e, getFaultResponse());
    } catch (GSSException e) {
        LOG.fine("GSS API exception: " + e.getMessage());
        throw ExceptionUtils.toNotAuthorizedException(e, getFaultResponse());
    } catch (PrivilegedActionException e) {
        LOG.fine("PrivilegedActionException: " + e.getMessage());
        throw ExceptionUtils.toNotAuthorizedException(e, getFaultResponse());
    }
}
Also used : GSSName(org.ietf.jgss.GSSName) Message(org.apache.cxf.message.Message) PrivilegedActionException(java.security.PrivilegedActionException) Subject(javax.security.auth.Subject) GSSException(org.ietf.jgss.GSSException) GSSContext(org.ietf.jgss.GSSContext) LoginException(javax.security.auth.login.LoginException)

Example 24 with GSSContext

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

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 AuthenticationException on authentication errors.
 */
static String kerberosChallenge(String server) throws AuthenticationException {
    KERBEROS_LOCK.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
        LOG.debug("Got valid challenge for host {}", serverName);
        return Base64.getEncoder().encodeToString(outToken);
    } catch (GSSException | IllegalAccessException | NoSuchFieldException | ClassNotFoundException e) {
        throw new AuthenticationException(e);
    } finally {
        KERBEROS_LOCK.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 25 with GSSContext

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

the class SpnegoAuthenticator method doAuthenticate.

@Override
protected boolean doAuthenticate(Request request, HttpServletResponse response) throws IOException {
    if (checkForCachedAuthentication(request, response, true)) {
        return true;
    }
    MessageBytes authorization = request.getCoyoteRequest().getMimeHeaders().getValue("authorization");
    if (authorization == null) {
        if (log.isDebugEnabled()) {
            log.debug(sm.getString("authenticator.noAuthHeader"));
        }
        response.setHeader(AUTH_HEADER_NAME, AUTH_HEADER_VALUE_NEGOTIATE);
        response.sendError(HttpServletResponse.SC_UNAUTHORIZED);
        return false;
    }
    authorization.toBytes();
    ByteChunk authorizationBC = authorization.getByteChunk();
    if (!authorizationBC.startsWithIgnoreCase("negotiate ", 0)) {
        if (log.isDebugEnabled()) {
            log.debug(sm.getString("spnegoAuthenticator.authHeaderNotNego"));
        }
        response.setHeader(AUTH_HEADER_NAME, AUTH_HEADER_VALUE_NEGOTIATE);
        response.sendError(HttpServletResponse.SC_UNAUTHORIZED);
        return false;
    }
    authorizationBC.setOffset(authorizationBC.getOffset() + 10);
    byte[] decoded = Base64.decodeBase64(authorizationBC.getBuffer(), authorizationBC.getOffset(), authorizationBC.getLength());
    if (getApplyJava8u40Fix()) {
        SpnegoTokenFixer.fix(decoded);
    }
    if (decoded.length == 0) {
        if (log.isDebugEnabled()) {
            log.debug(sm.getString("spnegoAuthenticator.authHeaderNoToken"));
        }
        response.setHeader(AUTH_HEADER_NAME, AUTH_HEADER_VALUE_NEGOTIATE);
        response.sendError(HttpServletResponse.SC_UNAUTHORIZED);
        return false;
    }
    LoginContext lc = null;
    GSSContext gssContext = null;
    byte[] outToken = null;
    Principal principal = null;
    try {
        try {
            lc = new LoginContext(getLoginConfigName());
            lc.login();
        } catch (LoginException e) {
            log.error(sm.getString("spnegoAuthenticator.serviceLoginFail"), e);
            response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
            return false;
        }
        Subject subject = lc.getSubject();
        // Assume the GSSContext is stateless
        // TODO: Confirm this assumption
        final GSSManager manager = GSSManager.getInstance();
        // IBM JDK only understands indefinite lifetime
        final int credentialLifetime;
        if (JreVendor.IS_IBM_JVM) {
            credentialLifetime = GSSCredential.INDEFINITE_LIFETIME;
        } else {
            credentialLifetime = GSSCredential.DEFAULT_LIFETIME;
        }
        final PrivilegedExceptionAction<GSSCredential> action = () -> manager.createCredential(null, credentialLifetime, new Oid("1.3.6.1.5.5.2"), GSSCredential.ACCEPT_ONLY);
        gssContext = manager.createContext(Subject.doAs(subject, action));
        outToken = Subject.doAs(lc.getSubject(), new AcceptAction(gssContext, decoded));
        if (outToken == null) {
            if (log.isDebugEnabled()) {
                log.debug(sm.getString("spnegoAuthenticator.ticketValidateFail"));
            }
            // Start again
            response.setHeader(AUTH_HEADER_NAME, AUTH_HEADER_VALUE_NEGOTIATE);
            response.sendError(HttpServletResponse.SC_UNAUTHORIZED);
            return false;
        }
        principal = Subject.doAs(subject, new AuthenticateAction(context.getRealm(), gssContext, storeDelegatedCredential));
    } catch (GSSException e) {
        if (log.isDebugEnabled()) {
            log.debug(sm.getString("spnegoAuthenticator.ticketValidateFail"), e);
        }
        response.setHeader(AUTH_HEADER_NAME, AUTH_HEADER_VALUE_NEGOTIATE);
        response.sendError(HttpServletResponse.SC_UNAUTHORIZED);
        return false;
    } catch (PrivilegedActionException e) {
        Throwable cause = e.getCause();
        if (cause instanceof GSSException) {
            if (log.isDebugEnabled()) {
                log.debug(sm.getString("spnegoAuthenticator.serviceLoginFail"), e);
            }
        } else {
            log.error(sm.getString("spnegoAuthenticator.serviceLoginFail"), e);
        }
        response.setHeader(AUTH_HEADER_NAME, AUTH_HEADER_VALUE_NEGOTIATE);
        response.sendError(HttpServletResponse.SC_UNAUTHORIZED);
        return false;
    } finally {
        if (gssContext != null) {
            try {
                gssContext.dispose();
            } catch (GSSException e) {
            // Ignore
            }
        }
        if (lc != null) {
            try {
                lc.logout();
            } catch (LoginException e) {
            // Ignore
            }
        }
    }
    // Send response token on success and failure
    response.setHeader(AUTH_HEADER_NAME, AUTH_HEADER_VALUE_NEGOTIATE + " " + Base64.encodeBase64String(outToken));
    if (principal != null) {
        register(request, response, principal, Constants.SPNEGO_METHOD, principal.getName(), null);
        Pattern p = noKeepAliveUserAgents;
        if (p != null) {
            MessageBytes ua = request.getCoyoteRequest().getMimeHeaders().getValue("user-agent");
            if (ua != null && p.matcher(ua.toString()).matches()) {
                response.setHeader("Connection", "close");
            }
        }
        return true;
    }
    response.sendError(HttpServletResponse.SC_UNAUTHORIZED);
    return false;
}
Also used : Pattern(java.util.regex.Pattern) ByteChunk(org.apache.tomcat.util.buf.ByteChunk) PrivilegedActionException(java.security.PrivilegedActionException) MessageBytes(org.apache.tomcat.util.buf.MessageBytes) Oid(org.ietf.jgss.Oid) Subject(javax.security.auth.Subject) LoginContext(javax.security.auth.login.LoginContext) GSSException(org.ietf.jgss.GSSException) GSSCredential(org.ietf.jgss.GSSCredential) GSSContext(org.ietf.jgss.GSSContext) GSSManager(org.ietf.jgss.GSSManager) LoginException(javax.security.auth.login.LoginException) Principal(java.security.Principal)

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