io.undertow.util.FlexBase64 Java Examples

The following examples show how to use io.undertow.util.FlexBase64. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: BasicSSLSessionInfo.java    From lams with GNU General Public License v2.0 6 votes vote down vote up
private static byte[] base64Decode(String sessionId) {
    try {
        ByteBuffer sessionIdBuffer = FlexBase64.decode(sessionId);
        byte[] sessionIdData;
        if (sessionIdBuffer.hasArray()) {
            sessionIdData = sessionIdBuffer.array();
        } else {
            sessionIdData = new byte[sessionIdBuffer.remaining()];
            sessionIdBuffer.get(sessionIdData);
        }
        return sessionIdData;
    } catch (IOException e) {
        //can happen if the session id is invalid
        return null;
    }
}
 
Example #2
Source File: BasicSSLSessionInfo.java    From quarkus-http with Apache License 2.0 6 votes vote down vote up
private static byte[] base64Decode(String sessionId) {
    try {
        ByteBuf sessionIdBuffer = FlexBase64.decode(sessionId);
        byte[] sessionIdData;
        if (sessionIdBuffer.hasArray()) {
            sessionIdData = sessionIdBuffer.array();
        } else {
            sessionIdData = new byte[sessionIdBuffer.readableBytes()];
            sessionIdBuffer.readBytes(sessionIdData);
        }
        return sessionIdData;
    } catch (IOException e) {
        //can happen if the session id is invalid
        return null;
    }
}
 
Example #3
Source File: TestMessagesReceivedInOrder.java    From quarkus-http with Apache License 2.0 5 votes vote down vote up
private static String md5(byte[] buffer) {
    try {
        MessageDigest md = MessageDigest.getInstance("MD5");
        md.update(buffer);
        byte[] digest = md.digest();
        return new String(FlexBase64.encodeBytes(digest, 0, digest.length, false));
    } catch (NoSuchAlgorithmException e) {
        // Should never happen
        throw new InternalError("MD5 not supported on this platform");
    }
}
 
Example #4
Source File: Oauth2DerefGetHandler.java    From light-oauth2 with Apache License 2.0 5 votes vote down vote up
@SuppressWarnings("unchecked")
private String authenticate(String authHeader) throws ApiException {
    String result = null;
    if (authHeader.toLowerCase(Locale.ENGLISH).startsWith(LOWERCASE_BASIC_PREFIX)) {
        String base64Challenge = authHeader.substring(PREFIX_LENGTH);
        String plainChallenge;
        try {
            ByteBuffer decode = FlexBase64.decode(base64Challenge);
            // assume charset is UTF_8
            Charset charset = StandardCharsets.UTF_8;
            plainChallenge = new String(decode.array(), decode.arrayOffset(), decode.limit(), charset);
            logger.debug("Found basic auth header %s (decoded using charset %s) in %s", plainChallenge, charset, authHeader);
            int colonPos;
            if ((colonPos = plainChallenge.indexOf(COLON)) > -1) {
                String clientId = plainChallenge.substring(0, colonPos);
                String clientSecret = plainChallenge.substring(colonPos + 1);
                // match with db/cached user credentials.
                IMap<String, Client> clients = CacheStartupHookProvider.hz.getMap("clients");
                Client client = clients.get(clientId);
                if(client == null) {
                    throw new ApiException(new Status(CLIENT_NOT_FOUND, clientId));
                }
                if(!HashUtil.validatePassword(clientSecret.toCharArray(), client.getClientSecret())) {
                    throw new ApiException(new Status(UNAUTHORIZED_CLIENT));
                }
                result = clientId;
            }
        } catch (IOException | NoSuchAlgorithmException | InvalidKeySpecException e) {
            logger.error("Exception:", e);
            throw new ApiException(new Status(RUNTIME_EXCEPTION));
        }
    }
    return result;
}
 
Example #5
Source File: LightGSSAPIAuthenticationMechanism.java    From light-oauth2 with Apache License 2.0 5 votes vote down vote up
@Override
public ChallengeResult sendChallenge(final HttpServerExchange exchange, final SecurityContext securityContext) {
    NegotiationContext negContext = exchange.getAttachment(NegotiationContext.ATTACHMENT_KEY);

    String header = NEGOTIATION_PLAIN;

    if (negContext != null) {
        byte[] responseChallenge = negContext.useResponseToken();
        exchange.putAttachment(NegotiationContext.ATTACHMENT_KEY, null);
        if (responseChallenge != null) {
            header = NEGOTIATE_PREFIX + FlexBase64.encodeString(responseChallenge, false);
        }
    } else {
        Subject server = null;
        try {
            server = subjectFactory.getSubjectForHost(getHostName(exchange));
        } catch (GeneralSecurityException e) {
            // Deliberately ignore - no Subject so don't offer GSSAPI is our main concern here.
        }
        if (server == null) {
            return ChallengeResult.NOT_SENT;
        }
    }

    exchange.getResponseHeaders().add(WWW_AUTHENTICATE, header);

    if(logger.isDebugEnabled()) logger.debug("Sending GSSAPI challenge for %s", exchange);
    return new ChallengeResult(true, UNAUTHORIZED);
}
 
Example #6
Source File: WebSocket13ClientHandshake.java    From lams with GNU General Public License v2.0 5 votes vote down vote up
protected final String solve(final String nonceBase64) {
    try {
        final String concat = nonceBase64 + MAGIC_NUMBER;
        final MessageDigest digest = MessageDigest.getInstance("SHA1");

        digest.update(concat.getBytes(StandardCharsets.UTF_8));
        final byte[] bytes = digest.digest();
        return FlexBase64.encodeString(bytes, false);
    } catch (NoSuchAlgorithmException e) {
        throw new RuntimeException(e);
    }
}
 
Example #7
Source File: WebSocket13ClientHandshake.java    From lams with GNU General Public License v2.0 5 votes vote down vote up
protected String createSecKey() {
    SecureRandom random = new SecureRandom();
    byte[] data = new byte[16];
    for (int i = 0; i < 4; ++i) {
        int val = random.nextInt();
        data[i * 4] = (byte) val;
        data[i * 4 + 1] = (byte) ((val >> 8) & 0xFF);
        data[i * 4 + 2] = (byte) ((val >> 16) & 0xFF);
        data[i * 4 + 3] = (byte) ((val >> 24) & 0xFF);
    }
    return FlexBase64.encodeString(data, false);
}
 
Example #8
Source File: DirectoryUtils.java    From lams with GNU General Public License v2.0 5 votes vote down vote up
/**
 * Generate the MD5 hash out of the given {@link ByteBuffer}
 */
private static String md5(byte[] buffer) {
    try {
        MessageDigest md = MessageDigest.getInstance("MD5");
        md.update(buffer);
        byte[] digest = md.digest();
        return new String(FlexBase64.encodeBytes(digest, 0, digest.length, false), StandardCharsets.US_ASCII);
    } catch (NoSuchAlgorithmException e) {
        // Should never happen
        throw new InternalError("MD5 not supported on this platform");
    }
}
 
Example #9
Source File: Http2ClearClientProvider.java    From lams with GNU General Public License v2.0 5 votes vote down vote up
public static String createSettingsFrame(OptionMap options, ByteBufferPool bufferPool) {
    PooledByteBuffer b = bufferPool.allocate();
    try {
        ByteBuffer currentBuffer = b.getBuffer();

        if (options.contains(UndertowOptions.HTTP2_SETTINGS_HEADER_TABLE_SIZE)) {
            pushOption(currentBuffer, Http2Setting.SETTINGS_HEADER_TABLE_SIZE, options.get(UndertowOptions.HTTP2_SETTINGS_HEADER_TABLE_SIZE));
        }
        if (options.contains(UndertowOptions.HTTP2_SETTINGS_ENABLE_PUSH)) {
            pushOption(currentBuffer, Http2Setting.SETTINGS_ENABLE_PUSH, options.get(UndertowOptions.HTTP2_SETTINGS_ENABLE_PUSH) ? 1 : 0);
        }

        if (options.contains(UndertowOptions.HTTP2_SETTINGS_MAX_CONCURRENT_STREAMS)) {
            pushOption(currentBuffer, Http2Setting.SETTINGS_MAX_CONCURRENT_STREAMS, options.get(UndertowOptions.HTTP2_SETTINGS_MAX_CONCURRENT_STREAMS));
        }

        if (options.contains(UndertowOptions.HTTP2_SETTINGS_INITIAL_WINDOW_SIZE)) {
            pushOption(currentBuffer, Http2Setting.SETTINGS_INITIAL_WINDOW_SIZE, options.get(UndertowOptions.HTTP2_SETTINGS_INITIAL_WINDOW_SIZE));
        }

        if (options.contains(UndertowOptions.HTTP2_SETTINGS_MAX_FRAME_SIZE)) {
            pushOption(currentBuffer, Http2Setting.SETTINGS_MAX_FRAME_SIZE, options.get(UndertowOptions.HTTP2_SETTINGS_MAX_FRAME_SIZE));
        }

        if (options.contains(UndertowOptions.HTTP2_SETTINGS_MAX_HEADER_LIST_SIZE)) {
            pushOption(currentBuffer, Http2Setting.SETTINGS_MAX_HEADER_LIST_SIZE, options.get(UndertowOptions.HTTP2_SETTINGS_MAX_HEADER_LIST_SIZE));
        } else if(options.contains(UndertowOptions.MAX_HEADER_SIZE)) {
            pushOption(currentBuffer, Http2Setting.SETTINGS_MAX_HEADER_LIST_SIZE, options.get(UndertowOptions.HTTP2_SETTINGS_MAX_HEADER_LIST_SIZE));
        }
        currentBuffer.flip();
        return FlexBase64.encodeStringURL(currentBuffer, false);
    } finally {
        b.close();
    }
}
 
Example #10
Source File: SslSessionIdAttribute.java    From lams with GNU General Public License v2.0 5 votes vote down vote up
@Override
public String readAttribute(HttpServerExchange exchange) {
    SSLSessionInfo ssl = exchange.getConnection().getSslSessionInfo();
    if(ssl == null || ssl.getSessionId() == null) {
        return null;
    }
    return FlexBase64.encodeString(ssl.getSessionId(), false);
}
 
Example #11
Source File: SimpleNonceManager.java    From lams with GNU General Public License v2.0 5 votes vote down vote up
private String createNonce(final byte[] prefix, final byte[] timeStamp) {
    byte[] hashedPart = generateHash(prefix, timeStamp);
    byte[] complete = new byte[9 + timeStamp.length + hashedPart.length];
    System.arraycopy(prefix, 0, complete, 0, 8);
    complete[8] = (byte) timeStamp.length;
    System.arraycopy(timeStamp, 0, complete, 9, timeStamp.length);
    System.arraycopy(hashedPart, 0, complete, 9 + timeStamp.length, hashedPart.length);

    return FlexBase64.encodeString(complete, false);
}
 
Example #12
Source File: SimpleNonceManager.java    From lams with GNU General Public License v2.0 5 votes vote down vote up
public SimpleNonceManager(final String hashAlg) {
    // Verify it is a valid algorithm (at least for now)
    MessageDigest digest = getDigest(hashAlg);

    this.hashAlg = hashAlg;
    this.hashLength = digest.getDigestLength();

    // Create a new secret only valid within this NonceManager instance.
    Random rand = new SecureRandom();
    byte[] secretBytes = new byte[32];
    rand.nextBytes(secretBytes);
    secret = FlexBase64.encodeString(digest.digest(secretBytes), false);
}
 
Example #13
Source File: GSSAPIAuthenticationMechanism.java    From lams with GNU General Public License v2.0 5 votes vote down vote up
public ChallengeResult sendChallenge(final HttpServerExchange exchange, final SecurityContext securityContext) {
    NegotiationContext negContext = exchange.getAttachment(NegotiationContext.ATTACHMENT_KEY);

    String header = NEGOTIATION_PLAIN;

    if (negContext != null) {
        byte[] responseChallenge = negContext.useResponseToken();
        exchange.putAttachment(NegotiationContext.ATTACHMENT_KEY, null);
        if (responseChallenge != null) {
            header = NEGOTIATE_PREFIX + FlexBase64.encodeString(responseChallenge, false);
        }
    } else {
        Subject server = null;
        try {
            server = subjectFactory.getSubjectForHost(getHostName(exchange));
        } catch (GeneralSecurityException e) {
            // Deliberately ignore - no Subject so don't offer GSSAPI is our main concern here.
        }
        if (server == null) {
            return ChallengeResult.NOT_SENT;
        }
    }

    exchange.getResponseHeaders().add(WWW_AUTHENTICATE, header);

    UndertowLogger.SECURITY_LOGGER.debugf("Sending GSSAPI challenge for %s", exchange);
    return new ChallengeResult(true, UNAUTHORIZED);
}
 
Example #14
Source File: DirectoryUtils.java    From quarkus-http with Apache License 2.0 5 votes vote down vote up
/**
 * Generate the MD5 hash out of the given {@link ByteBuffer}
 */
private static String md5(byte[] buffer) {
    try {
        MessageDigest md = MessageDigest.getInstance("MD5");
        md.update(buffer);
        byte[] digest = md.digest();
        return new String(FlexBase64.encodeBytes(digest, 0, digest.length, false), StandardCharsets.US_ASCII);
    } catch (NoSuchAlgorithmException e) {
        // Should never happen
        throw new InternalError("MD5 not supported on this platform");
    }
}
 
Example #15
Source File: WebsocketBasicAuthTestCase.java    From quarkus-http with Apache License 2.0 5 votes vote down vote up
@Test
public void testAuthenticatedWebsocket() throws Exception {
    ProgramaticClientEndpoint endpoint = new ProgramaticClientEndpoint();
    ClientEndpointConfig clientEndpointConfig = ClientEndpointConfig.Builder.create().configurator(new ClientConfigurator(){
        @Override
        public void beforeRequest(Map<String, List<String>> headers) {
            headers.put(AUTHORIZATION.toString(), Collections.singletonList(BASIC + " " + FlexBase64.encodeString("user1:password1".getBytes(), false)));
        }
    }).build();
    ContainerProvider.getWebSocketContainer().connectToServer(endpoint, clientEndpointConfig, new URI("ws://" + DefaultServer.getHostAddress("default") + ":" + DefaultServer.getHostPort("default") + "/servletContext/secured"));
    Assert.assertEquals("user1", endpoint.getResponses().poll(15, TimeUnit.SECONDS));
    endpoint.session.close();
    endpoint.closeLatch.await(10, TimeUnit.SECONDS);
}
 
Example #16
Source File: SslSessionIdAttribute.java    From quarkus-http with Apache License 2.0 5 votes vote down vote up
@Override
public String readAttribute(HttpServerExchange exchange) {
    SSLSessionInfo ssl = exchange.getSslSessionInfo();
    if(ssl == null || ssl.getSessionId() == null) {
        return null;
    }
    return FlexBase64.encodeString(ssl.getSessionId(), false);
}
 
Example #17
Source File: SimpleNonceManager.java    From quarkus-http with Apache License 2.0 5 votes vote down vote up
private String createNonce(final byte[] prefix, final byte[] timeStamp) {
    byte[] hashedPart = generateHash(prefix, timeStamp);
    byte[] complete = new byte[9 + timeStamp.length + hashedPart.length];
    System.arraycopy(prefix, 0, complete, 0, 8);
    complete[8] = (byte) timeStamp.length;
    System.arraycopy(timeStamp, 0, complete, 9, timeStamp.length);
    System.arraycopy(hashedPart, 0, complete, 9 + timeStamp.length, hashedPart.length);

    return FlexBase64.encodeString(complete, false);
}
 
Example #18
Source File: SimpleNonceManager.java    From quarkus-http with Apache License 2.0 5 votes vote down vote up
public SimpleNonceManager(final String hashAlg) {
    // Verify it is a valid algorithm (at least for now)
    MessageDigest digest = getDigest(hashAlg);

    this.hashAlg = hashAlg;
    this.hashLength = digest.getDigestLength();

    // Create a new secret only valid within this NonceManager instance.
    Random rand = new SecureRandom();
    byte[] secretBytes = new byte[32];
    rand.nextBytes(secretBytes);
    secret = FlexBase64.encodeString(digest.digest(secretBytes), false);
}
 
Example #19
Source File: GSSAPIAuthenticationMechanism.java    From quarkus-http with Apache License 2.0 5 votes vote down vote up
public ChallengeResult sendChallenge(final HttpServerExchange exchange, final SecurityContext securityContext) {
    NegotiationContext negContext = exchange.getAttachment(NegotiationContext.ATTACHMENT_KEY);

    String header = NEGOTIATION_PLAIN;

    if (negContext != null) {
        byte[] responseChallenge = negContext.useResponseToken();
        exchange.putAttachment(NegotiationContext.ATTACHMENT_KEY, null);
        if (responseChallenge != null) {
            header = NEGOTIATE_PREFIX + FlexBase64.encodeString(responseChallenge, false);
        }
    } else {
        Subject server = null;
        try {
            server = subjectFactory.getSubjectForHost(getHostName(exchange));
        } catch (GeneralSecurityException e) {
            // Deliberately ignore - no Subject so don't offer GSSAPI is our main concern here.
        }
        if (server == null) {
            return ChallengeResult.NOT_SENT;
        }
    }

    exchange.addResponseHeader(WWW_AUTHENTICATE, header);

    UndertowLogger.SECURITY_LOGGER.debugf("Sending GSSAPI challenge for %s", exchange);
    return new ChallengeResult(true, UNAUTHORIZED);
}
 
Example #20
Source File: LogoutHandler.java    From wildfly-core with GNU Lesser General Public License v2.1 4 votes vote down vote up
@Override
public void handleRequest(HttpServerExchange exchange) throws Exception {
    final HeaderMap requestHeaders = exchange.getRequestHeaders();
    final HeaderMap responseHeaders = exchange.getResponseHeaders();

    String referrer = responseHeaders.getFirst(REFERER);
    String protocol = exchange.getRequestScheme();
    String host = null;
    if (referrer != null) {
        try {
            URI uri = new URI(referrer);
            protocol = uri.getScheme();
            host = uri.getHost() + portPortion(protocol, uri.getPort());
        } catch (URISyntaxException e) {
        }
    }
    if (host == null) {
        host = requestHeaders.getFirst(HOST);
        if (host == null) {
            exchange.setStatusCode(StatusCodes.INTERNAL_SERVER_ERROR);
            return;
        }
    }

    /*
     * Main sequence of events:
     *
     * 1. Redirect to self using user:pass@host form of authority. This forces Safari to overwrite its cache. (Also
     * forces FF and Chrome, but not absolutely necessary) Set the exit flag as a state signal for step 3
     *
     * 2. Send 401 digest without a nonce stale marker, this will force FF and Chrome and likely other browsers to
     * assume an invalid (old) password. In the case of Opera, which doesn't invalidate under such a circumstance,
     * send an invalid realm. This will overwrite its auth cache, since it indexes it by host and not realm.
     *
     * 3. The credentials in 307 redirect wlll be transparently accepted and a final redirect to the console is
     * performed. Opera ignores these, so the user must hit escape which will use javascript to perform the redirect
     *
     * In the case of Internet Explorer, all of this will be bypassed and will simply redirect to the console. The console
     * MUST use a special javascript call before redirecting to logout.
     */
    String userAgent = requestHeaders.getFirst(USER_AGENT);
    boolean opera = userAgent != null && userAgent.contains("Opera");
    boolean win = !opera && userAgent != null && (userAgent.contains("MSIE") || userAgent.contains("Trident"));

    String rawQuery = exchange.getQueryString();
    boolean exit = rawQuery != null && rawQuery.contains(EXIT);



    if (win) {
        responseHeaders.add(LOCATION, protocol + "://" + host + "/");
        exchange.setStatusCode(StatusCodes.TEMPORARY_REDIRECT);
    } else {
        // Do the redirects to finish the logout
        String authorization = requestHeaders.getFirst(AUTHORIZATION);

        boolean digest = true;
        Map<String, Deque<String>> parameters = exchange.getQueryParameters();
        if (parameters.containsKey(MECHANISM)) {
            digest = !BASIC.equals(parameters.get(MECHANISM).getFirst());
        }
        if (authorization != null && authorization.length() > BASIC.length()
                && BASIC.equalsIgnoreCase(authorization.substring(0, BASIC.length()))) {
            digest = false;
            ByteBuffer decode = FlexBase64.decode(authorization.substring(6));
            authorization = new String(decode.array(), decode.arrayOffset(), decode.limit(), UTF_8);
        }

        if (authorization == null || !authorization.contains("enter-login-here")) {
            if (!exit) {
                responseHeaders.add(LOCATION, protocol + "://enter-login-here:blah@" + host + "/logout?" + EXIT + "&"
                        + MECHANISM + "=" + (digest ? DIGEST : BASIC));
                exchange.setStatusCode(StatusCodes.TEMPORARY_REDIRECT);
                return;
            }

            mechanism(opera, digest).sendChallenge(exchange, null);
            String reply = "<html><script type='text/javascript'>window.location=\"" + protocol + "://" + host
                    + "/\";</script></html>";
            exchange.setStatusCode(StatusCodes.UNAUTHORIZED);
            exchange.getResponseSender().send(reply, IoCallback.END_EXCHANGE);
            return;
        }

        // Success, now back to the login screen
        responseHeaders.add(LOCATION, protocol + "://" + host + "/");
        exchange.setStatusCode(StatusCodes.TEMPORARY_REDIRECT);
    }
}
 
Example #21
Source File: GSSAPIAuthenticationMechanism.java    From lams with GNU General Public License v2.0 4 votes vote down vote up
@Override
public AuthenticationMechanismOutcome authenticate(final HttpServerExchange exchange,
                                                   final SecurityContext securityContext) {
    ServerConnection connection = exchange.getConnection();
    NegotiationContext negContext = connection.getAttachment(NegotiationContext.ATTACHMENT_KEY);
    if (negContext != null) {

        UndertowLogger.SECURITY_LOGGER.debugf("Existing negotiation context found for %s", exchange);
        exchange.putAttachment(NegotiationContext.ATTACHMENT_KEY, negContext);
        if (negContext.isEstablished()) {
            IdentityManager identityManager = getIdentityManager(securityContext);
            final Account account = identityManager.verify(new GSSContextCredential(negContext.getGssContext()));
            if (account != null) {
                securityContext.authenticationComplete(account, name, false);
                UndertowLogger.SECURITY_LOGGER.debugf("Authenticated as user %s with existing GSSAPI negotiation context for %s", account.getPrincipal().getName(), exchange);
                return AuthenticationMechanismOutcome.AUTHENTICATED;
            } else {
                UndertowLogger.SECURITY_LOGGER.debugf("Failed to authenticate with existing GSSAPI negotiation context for %s", exchange);
                return AuthenticationMechanismOutcome.NOT_AUTHENTICATED;
            }
        }
    }

    List<String> authHeaders = exchange.getRequestHeaders().get(AUTHORIZATION);
    if (authHeaders != null) {
        for (String current : authHeaders) {
            if (current.startsWith(NEGOTIATE_PREFIX)) {
                String base64Challenge = current.substring(NEGOTIATE_PREFIX.length());
                try {
                    ByteBuffer challenge = FlexBase64.decode(base64Challenge);
                    return runGSSAPI(exchange, challenge, securityContext);
                } catch (IOException e) {
                }

                // By this point we had a header we should have been able to verify but for some reason
                // it was not correctly structured.
                return AuthenticationMechanismOutcome.NOT_AUTHENTICATED;
            }
        }
    }

    // No suitable header was found so authentication was not even attempted.
    return AuthenticationMechanismOutcome.NOT_ATTEMPTED;
}
 
Example #22
Source File: LightBasicAuthenticationMechanism.java    From light-oauth2 with Apache License 2.0 4 votes vote down vote up
/**
 * @see io.undertow.server.HttpHandler#handleRequest(io.undertow.server.HttpServerExchange)
 */
@Override
public AuthenticationMechanismOutcome authenticate(HttpServerExchange exchange, SecurityContext securityContext) {

    List<String> authHeaders = exchange.getRequestHeaders().get(AUTHORIZATION);
    if (authHeaders != null) {
        for (String current : authHeaders) {
            if (current.toLowerCase(Locale.ENGLISH).startsWith(LOWERCASE_BASIC_PREFIX)) {

                String base64Challenge = current.substring(PREFIX_LENGTH);
                String plainChallenge = null;
                try {
                    ByteBuffer decode = FlexBase64.decode(base64Challenge);

                    Charset charset = this.charset;
                    if(!userAgentCharsets.isEmpty()) {
                        String ua = exchange.getRequestHeaders().getFirst(Headers.USER_AGENT);
                        if(ua != null) {
                            for (Map.Entry<Pattern, Charset> entry : userAgentCharsets.entrySet()) {
                                if(entry.getKey().matcher(ua).find()) {
                                    charset = entry.getValue();
                                    break;
                                }
                            }
                        }
                    }

                    plainChallenge = new String(decode.array(), decode.arrayOffset(), decode.limit(), charset);
                    if(logger.isDebugEnabled()) logger.debug("Found basic auth header %s (decoded using charset %s) in %s", plainChallenge, charset, exchange);
                } catch (IOException e) {
                    logger.error("Failed to decode basic auth header " + base64Challenge + " in " + exchange, e);
                }
                int colonPos;
                if (plainChallenge != null && (colonPos = plainChallenge.indexOf(COLON)) > -1) {
                    String userName = plainChallenge.substring(0, colonPos);
                    char[] password = plainChallenge.substring(colonPos + 1).toCharArray();

                    // get clientAuthClass and userType
                    String clientAuthClass = null;
                    String userType = null;
                    Map<String, Deque<String>> params = exchange.getQueryParameters();
                    Deque<String> clientIdDeque = params.get("client_id");
                    if(clientIdDeque != null) {
                        String clientId = clientIdDeque.getFirst();
                        IMap<String, Client> clients = CacheStartupHookProvider.hz.getMap("clients");
                        Client client = clients.get(clientId);
                        if(client != null) {
                            clientAuthClass = client.getAuthenticateClass();
                        }
                    }
                    Deque<String> userTypeDeque = params.get("user_type");
                    if(userTypeDeque != null) {
                        userType = userTypeDeque.getFirst();
                    }

                    IdentityManager idm = getIdentityManager(securityContext);
                    LightPasswordCredential credential = new LightPasswordCredential(password, clientAuthClass, userType, exchange);
                    try {
                        final AuthenticationMechanismOutcome result;
                        Account account = idm.verify(userName, credential);
                        if (account != null) {
                            securityContext.authenticationComplete(account, name, false);
                            result = AuthenticationMechanismOutcome.AUTHENTICATED;
                        } else {
                            securityContext.authenticationFailed(MESSAGES.authenticationFailed(userName), name);
                            result = AuthenticationMechanismOutcome.NOT_AUTHENTICATED;
                        }
                        return result;
                    } finally {
                        clear(password);
                    }
                }

                // By this point we had a header we should have been able to verify but for some reason
                // it was not correctly structured.
                return AuthenticationMechanismOutcome.NOT_AUTHENTICATED;
            }
        }
    }

    // No suitable header has been found in this request,
    return AuthenticationMechanismOutcome.NOT_ATTEMPTED;
}
 
Example #23
Source File: LightGSSAPIAuthenticationMechanism.java    From light-oauth2 with Apache License 2.0 4 votes vote down vote up
@Override
public AuthenticationMechanismOutcome run() throws GSSException {
    NegotiationContext negContext = exchange.getAttachment(NegotiationContext.ATTACHMENT_KEY);
    if (negContext == null) {
        negContext = new NegotiationContext();
        exchange.putAttachment(NegotiationContext.ATTACHMENT_KEY, negContext);
        // Also cache it on the connection for future calls.
        exchange.getConnection().putAttachment(NegotiationContext.ATTACHMENT_KEY, negContext);
    }

    GSSContext gssContext = negContext.getGssContext();
    if (gssContext == null) {
        GSSManager manager = GSSManager.getInstance();

        GSSCredential credential = manager.createCredential(null, GSSCredential.INDEFINITE_LIFETIME, mechanisms, GSSCredential.ACCEPT_ONLY);

        gssContext = manager.createContext(credential);

        negContext.setGssContext(gssContext);
    }

    byte[] respToken = gssContext.acceptSecContext(challenge.array(), challenge.arrayOffset(), challenge.limit());
    negContext.setResponseToken(respToken);

    if (negContext.isEstablished()) {

        if (respToken != null) {
            // There will be no further challenge but we do have a token so set it here.
            exchange.getResponseHeaders().add(WWW_AUTHENTICATE,
                    NEGOTIATE_PREFIX + FlexBase64.encodeString(respToken, false));
        }
        IdentityManager identityManager = securityContext.getIdentityManager();
        // get the client authenticate class and user type from the exchange.
        String clientAuthClass = null;
        String userType = null;
        Map<String, Deque<String>> params = exchange.getQueryParameters();
        Deque<String> clientIdDeque = params.get("client_id");
        if(clientIdDeque != null) {
            String clientId = clientIdDeque.getFirst();
            IMap<String, Client> clients = CacheStartupHookProvider.hz.getMap("clients");
            Client client = clients.get(clientId);
            if(client != null) {
                clientAuthClass = client.getAuthenticateClass();
            }
        }
        Deque<String> userTypeDeque = params.get("user_type");
        if(userTypeDeque != null) {
            userType = userTypeDeque.getFirst();
        }

        final Account account = identityManager.verify(new LightGSSContextCredential(negContext.getGssContext(), clientAuthClass, userType));
        if (account != null) {
            securityContext.authenticationComplete(account, name, false);
            return AuthenticationMechanismOutcome.AUTHENTICATED;
        } else {
            return AuthenticationMechanismOutcome.NOT_AUTHENTICATED;
        }
    } else {
        // This isn't a failure but as the context is not established another round trip with the client is needed.
        return AuthenticationMechanismOutcome.NOT_AUTHENTICATED;
    }
}
 
Example #24
Source File: GSSAPIAuthenticationMechanism.java    From quarkus-http with Apache License 2.0 4 votes vote down vote up
@Override
public AuthenticationMechanismOutcome authenticate(final HttpServerExchange exchange,
                                                   final SecurityContext securityContext) {
    NegotiationContext negContext = exchange.getAttachment(NegotiationContext.ATTACHMENT_KEY);
    if (negContext != null) {

        UndertowLogger.SECURITY_LOGGER.debugf("Existing negotiation context found for %s", exchange);
        exchange.putAttachment(NegotiationContext.ATTACHMENT_KEY, negContext);
        if (negContext.isEstablished()) {
            IdentityManager identityManager = getIdentityManager(securityContext);
            final Account account = identityManager.verify(new GSSContextCredential(negContext.getGssContext()));
            if (account != null) {
                securityContext.authenticationComplete(account, name, false);
                UndertowLogger.SECURITY_LOGGER.debugf("Authenticated as user %s with existing GSSAPI negotiation context for %s", account.getPrincipal().getName(), exchange);
                return AuthenticationMechanismOutcome.AUTHENTICATED;
            } else {
                UndertowLogger.SECURITY_LOGGER.debugf("Failed to authenticate with existing GSSAPI negotiation context for %s", exchange);
                return AuthenticationMechanismOutcome.NOT_AUTHENTICATED;
            }
        }
    }

    List<String> authHeaders = exchange.getRequestHeaders(AUTHORIZATION);
    if (authHeaders != null) {
        for (String current : authHeaders) {
            if (current.startsWith(NEGOTIATE_PREFIX)) {
                String base64Challenge = current.substring(NEGOTIATE_PREFIX.length());
                try {
                    ByteBuf challenge = FlexBase64.decode(base64Challenge);
                    return runGSSAPI(exchange, challenge, securityContext);
                } catch (IOException e) {
                }

                // By this point we had a header we should have been able to verify but for some reason
                // it was not correctly structured.
                return AuthenticationMechanismOutcome.NOT_AUTHENTICATED;
            }
        }
    }

    // No suitable header was found so authentication was not even attempted.
    return AuthenticationMechanismOutcome.NOT_ATTEMPTED;
}
 
Example #25
Source File: LightGSSAPIAuthenticationMechanism.java    From light-oauth2 with Apache License 2.0 4 votes vote down vote up
@Override
public AuthenticationMechanismOutcome authenticate(final HttpServerExchange exchange,
                                                   final SecurityContext securityContext) {
    ServerConnection connection = exchange.getConnection();
    NegotiationContext negContext = connection.getAttachment(NegotiationContext.ATTACHMENT_KEY);
    if (negContext != null) {

        if(logger.isDebugEnabled()) logger.debug("Existing negotiation context found for %s", exchange);
        exchange.putAttachment(NegotiationContext.ATTACHMENT_KEY, negContext);
        if (negContext.isEstablished()) {
            IdentityManager identityManager = getIdentityManager(securityContext);
            // get the client authenticate class and user type from the exchange.
            String clientAuthClass = null;
            String userType = null;
            Map<String, Deque<String>> params = exchange.getQueryParameters();
            Deque<String> clientIdDeque = params.get("client_id");
            if(clientIdDeque != null) {
                String clientId = clientIdDeque.getFirst();
                IMap<String, Client> clients = CacheStartupHookProvider.hz.getMap("clients");
                Client client = clients.get(clientId);
                if(client != null) {
                    clientAuthClass = client.getAuthenticateClass();
                }
            }
            Deque<String> userTypeDeque = params.get("user_type");
            if(userTypeDeque != null) {
                userType = userTypeDeque.getFirst();
            }

            final Account account = identityManager.verify(new LightGSSContextCredential(negContext.getGssContext(), clientAuthClass, userType));
            if (account != null) {
                securityContext.authenticationComplete(account, name, false);
                if(logger.isDebugEnabled()) logger.debug("Authenticated as user %s with existing GSSAPI negotiation context for %s", account.getPrincipal().getName(), exchange);
                return AuthenticationMechanismOutcome.AUTHENTICATED;
            } else {
                if(logger.isDebugEnabled()) logger.debug("Failed to authenticate with existing GSSAPI negotiation context for %s", exchange);
                return AuthenticationMechanismOutcome.NOT_AUTHENTICATED;
            }
        }
    }

    List<String> authHeaders = exchange.getRequestHeaders().get(AUTHORIZATION);
    if (authHeaders != null) {
        for (String current : authHeaders) {
            if (current.startsWith(NEGOTIATE_PREFIX)) {
                String base64Challenge = current.substring(NEGOTIATE_PREFIX.length());
                try {
                    ByteBuffer challenge = FlexBase64.decode(base64Challenge);
                    return runGSSAPI(exchange, challenge, securityContext);
                } catch (IOException e) {
                }

                // By this point we had a header we should have been able to verify but for some reason
                // it was not correctly structured.
                return AuthenticationMechanismOutcome.NOT_AUTHENTICATED;
            }
        }
    }

    // No suitable header was found so authentication was not even attempted.
    return AuthenticationMechanismOutcome.NOT_ATTEMPTED;
}
 
Example #26
Source File: GSSAPIAuthenticationMechanism.java    From quarkus-http with Apache License 2.0 4 votes vote down vote up
public AuthenticationMechanismOutcome run() throws GSSException {
    NegotiationContext negContext = exchange.getAttachment(NegotiationContext.ATTACHMENT_KEY);
    if (negContext == null) {
        negContext = new NegotiationContext();
        exchange.putAttachment(NegotiationContext.ATTACHMENT_KEY, negContext);
    }

    GSSContext gssContext = negContext.getGssContext();
    if (gssContext == null) {
        GSSManager manager = GSSManager.getInstance();

        GSSCredential credential = manager.createCredential(null, GSSCredential.INDEFINITE_LIFETIME, mechanisms, GSSCredential.ACCEPT_ONLY);

        gssContext = manager.createContext(credential);

        negContext.setGssContext(gssContext);
    }

    byte[] respToken = gssContext.acceptSecContext(challenge.array(), challenge.arrayOffset(), challenge.writerIndex());
    negContext.setResponseToken(respToken);

    if (negContext.isEstablished()) {

        if (respToken != null) {
            // There will be no further challenge but we do have a token so set it here.
            exchange.addResponseHeader(WWW_AUTHENTICATE,
                    NEGOTIATE_PREFIX + FlexBase64.encodeString(respToken, false));
        }
        IdentityManager identityManager = securityContext.getIdentityManager();
        final Account account = identityManager.verify(new GSSContextCredential(negContext.getGssContext()));
        if (account != null) {
            securityContext.authenticationComplete(account, name, false);
            return AuthenticationMechanismOutcome.AUTHENTICATED;
        } else {
            return AuthenticationMechanismOutcome.NOT_AUTHENTICATED;
        }
    } else {
        // This isn't a failure but as the context is not established another round trip with the client is needed.
        return AuthenticationMechanismOutcome.NOT_AUTHENTICATED;
    }
}
 
Example #27
Source File: SimpleNonceManager.java    From quarkus-http with Apache License 2.0 4 votes vote down vote up
/**
 * Verify a previously unknown nonce and return the {@link NonceKey} representation for the nonce.
 * <p>
 * Later when a nonce is re-used we can match based on the String alone - the information embedded within the nonce will be
 * cached with it.
 * <p>
 * This stage of the verification simply extracts the prefix and the embedded timestamp and recreates a new hashed and
 * Base64 nonce based on the local secret - if the newly generated nonce matches the supplied one we accept it was created
 * by this nonce manager.
 * <p>
 * This verification does not validate that the timestamp is within a valid time period.
 *
 * @param nonce -
 * @return
 */
private Nonce verifyUnknownNonce(final String nonce, final int nonceCount) {
    byte[] complete;
    int offset;
    int length;
    try {
        ByteBuf decode = FlexBase64.decode(nonce);
        complete = decode.array();
        offset = decode.arrayOffset();
        length = decode.writerIndex() - offset;
    } catch (IOException e) {
        throw MESSAGES.invalidBase64Token(e);
    }

    int timeStampLength = complete[offset + 8];
    // A sanity check to try and verify the sizes we expect from the arrays are correct.
    if (hashLength > 0) {
        int expectedLength = 9 + timeStampLength + hashLength;
        if (length != expectedLength) {
            throw MESSAGES.invalidNonceReceived();
        } else if (timeStampLength + 1 >= length)
            throw MESSAGES.invalidNonceReceived();
    }

    byte[] prefix = new byte[8];
    System.arraycopy(complete, offset, prefix, 0, 8);
    byte[] timeStampBytes = new byte[timeStampLength];
    System.arraycopy(complete, offset + 9, timeStampBytes, 0, timeStampBytes.length);

    String expectedNonce = createNonce(prefix, timeStampBytes);

    if (expectedNonce.equals(nonce)) {
        try {
            long timeStamp = Long.parseLong(new String(timeStampBytes, StandardCharsets.UTF_8));

            return new Nonce(expectedNonce, timeStamp, nonceCount);
        } catch (NumberFormatException dropped) {
        }
    }

    return null;
}
 
Example #28
Source File: BasicAuthenticationMechanism.java    From quarkus-http with Apache License 2.0 4 votes vote down vote up
/**
 * @see io.undertow.server.HttpHandler#handleRequest(io.undertow.server.HttpServerExchange)
 */
@Override
public AuthenticationMechanismOutcome authenticate(HttpServerExchange exchange, SecurityContext securityContext) {

    List<String> authHeaders = exchange.getRequestHeaders(AUTHORIZATION);
    if (authHeaders != null) {
        for (String current : authHeaders) {
            if (current.toLowerCase(Locale.ENGLISH).startsWith(LOWERCASE_BASIC_PREFIX)) {

                String base64Challenge = current.substring(PREFIX_LENGTH);
                String plainChallenge = null;
                try {
                    ByteBuf decode = FlexBase64.decode(base64Challenge);

                    Charset charset = this.charset;
                    if(!userAgentCharsets.isEmpty()) {
                        String ua = exchange.getRequestHeader(HttpHeaderNames.USER_AGENT);
                        if(ua != null) {
                            for (Map.Entry<Pattern, Charset> entry : userAgentCharsets.entrySet()) {
                                if(entry.getKey().matcher(ua).find()) {
                                    charset = entry.getValue();
                                    break;
                                }
                            }
                        }
                    }

                    plainChallenge = new String(decode.array(), decode.arrayOffset(), decode.writerIndex(), charset);
                    UndertowLogger.SECURITY_LOGGER.debugf("Found basic auth header %s (decoded using charset %s) in %s", plainChallenge, charset, exchange);
                } catch (IOException e) {
                    UndertowLogger.SECURITY_LOGGER.debugf(e, "Failed to decode basic auth header %s in %s", base64Challenge, exchange);
                }
                int colonPos;
                if (plainChallenge != null && (colonPos = plainChallenge.indexOf(COLON)) > -1) {
                    String userName = plainChallenge.substring(0, colonPos);
                    char[] password = plainChallenge.substring(colonPos + 1).toCharArray();

                    IdentityManager idm = getIdentityManager(securityContext);
                    PasswordCredential credential = new PasswordCredential(password);
                    try {
                        final AuthenticationMechanismOutcome result;
                        Account account = idm.verify(userName, credential);
                        if (account != null) {
                            securityContext.authenticationComplete(account, name, false);
                            result = AuthenticationMechanismOutcome.AUTHENTICATED;
                        } else {
                            securityContext.authenticationFailed(MESSAGES.authenticationFailed(userName), name);
                            result = AuthenticationMechanismOutcome.NOT_AUTHENTICATED;
                        }
                        return result;
                    } finally {
                        clear(password);
                    }
                }

                // By this point we had a header we should have been able to verify but for some reason
                // it was not correctly structured.
                return AuthenticationMechanismOutcome.NOT_AUTHENTICATED;
            }
        }
    }

    // No suitable header has been found in this request,
    return AuthenticationMechanismOutcome.NOT_ATTEMPTED;
}
 
Example #29
Source File: BasicAuthenticationMechanism.java    From lams with GNU General Public License v2.0 4 votes vote down vote up
/**
 * @see io.undertow.server.HttpHandler#handleRequest(io.undertow.server.HttpServerExchange)
 */
@Override
public AuthenticationMechanismOutcome authenticate(HttpServerExchange exchange, SecurityContext securityContext) {

    List<String> authHeaders = exchange.getRequestHeaders().get(AUTHORIZATION);
    if (authHeaders != null) {
        for (String current : authHeaders) {
            if (current.toLowerCase(Locale.ENGLISH).startsWith(LOWERCASE_BASIC_PREFIX)) {

                String base64Challenge = current.substring(PREFIX_LENGTH);
                String plainChallenge = null;
                try {
                    ByteBuffer decode = FlexBase64.decode(base64Challenge);

                    Charset charset = this.charset;
                    if(!userAgentCharsets.isEmpty()) {
                        String ua = exchange.getRequestHeaders().getFirst(Headers.USER_AGENT);
                        if(ua != null) {
                            for (Map.Entry<Pattern, Charset> entry : userAgentCharsets.entrySet()) {
                                if(entry.getKey().matcher(ua).find()) {
                                    charset = entry.getValue();
                                    break;
                                }
                            }
                        }
                    }

                    plainChallenge = new String(decode.array(), decode.arrayOffset(), decode.limit(), charset);
                    UndertowLogger.SECURITY_LOGGER.debugf("Found basic auth header %s (decoded using charset %s) in %s", plainChallenge, charset, exchange);
                } catch (IOException e) {
                    UndertowLogger.SECURITY_LOGGER.debugf(e, "Failed to decode basic auth header %s in %s", base64Challenge, exchange);
                }
                int colonPos;
                if (plainChallenge != null && (colonPos = plainChallenge.indexOf(COLON)) > -1) {
                    String userName = plainChallenge.substring(0, colonPos);
                    char[] password = plainChallenge.substring(colonPos + 1).toCharArray();

                    IdentityManager idm = getIdentityManager(securityContext);
                    PasswordCredential credential = new PasswordCredential(password);
                    try {
                        final AuthenticationMechanismOutcome result;
                        Account account = idm.verify(userName, credential);
                        if (account != null) {
                            securityContext.authenticationComplete(account, name, false);
                            result = AuthenticationMechanismOutcome.AUTHENTICATED;
                        } else {
                            securityContext.authenticationFailed(MESSAGES.authenticationFailed(userName), name);
                            result = AuthenticationMechanismOutcome.NOT_AUTHENTICATED;
                        }
                        return result;
                    } finally {
                        clear(password);
                    }
                }

                // By this point we had a header we should have been able to verify but for some reason
                // it was not correctly structured.
                return AuthenticationMechanismOutcome.NOT_AUTHENTICATED;
            }
        }
    }

    // No suitable header has been found in this request,
    return AuthenticationMechanismOutcome.NOT_ATTEMPTED;
}
 
Example #30
Source File: SimpleNonceManager.java    From lams with GNU General Public License v2.0 4 votes vote down vote up
/**
 * Verify a previously unknown nonce and return the {@link NonceKey} representation for the nonce.
 *
 * Later when a nonce is re-used we can match based on the String alone - the information embedded within the nonce will be
 * cached with it.
 *
 * This stage of the verification simply extracts the prefix and the embedded timestamp and recreates a new hashed and
 * Base64 nonce based on the local secret - if the newly generated nonce matches the supplied one we accept it was created
 * by this nonce manager.
 *
 * This verification does not validate that the timestamp is within a valid time period.
 *
 * @param nonce -
 * @return
 */
private Nonce verifyUnknownNonce(final String nonce, final int nonceCount) {
    byte[] complete;
    int offset;
    int length;
    try {
        ByteBuffer decode = FlexBase64.decode(nonce);
        complete = decode.array();
        offset = decode.arrayOffset();
        length = decode.limit() - offset;
    } catch (IOException e) {
        throw MESSAGES.invalidBase64Token(e);
    }

    int timeStampLength = complete[offset + 8];
    // A sanity check to try and verify the sizes we expect from the arrays are correct.
    if (hashLength > 0) {
        int expectedLength = 9 + timeStampLength + hashLength;
        if (length != expectedLength) {
            throw MESSAGES.invalidNonceReceived();
        } else if (timeStampLength + 1 >= length)
            throw MESSAGES.invalidNonceReceived();
    }

    byte[] prefix = new byte[8];
    System.arraycopy(complete, offset, prefix, 0, 8);
    byte[] timeStampBytes = new byte[timeStampLength];
    System.arraycopy(complete, offset + 9, timeStampBytes, 0, timeStampBytes.length);

    String expectedNonce = createNonce(prefix, timeStampBytes);

    if (expectedNonce.equals(nonce)) {
        try {
            long timeStamp = Long.parseLong(new String(timeStampBytes, StandardCharsets.UTF_8));

            return new Nonce(expectedNonce, timeStamp, nonceCount);
        } catch (NumberFormatException dropped) {
        }
    }

    return null;
}