private void notifyAuthenticationStatus(Credentials credentials,
            boolean failed) throws GuacamoleException {

        // Ignore requests that do not contain explicit parameters of any kind
        if (credentials.isEmpty())
            return;

        // Determine originating address of the authentication request
        String address = credentials.getRemoteAddress();
        if (address == null)
            throw new GuacamoleServerException("Source address cannot be determined.");

        // Get current failure status for the address associated with the
        // authentication request, adding/updating that status if the request
        // was itself a failure
        AuthenticationFailureStatus status;
        if (failed) {
            status = getAuthenticationFailure(address);
            logger.info("Authentication has failed for address \"{}\" (current total failures: {}/{}).",
                    address, status.getFailures(), maxAttempts);
        }
        else
            status = failures.getIfPresent(address);

        if (status != null) {

            // Explicitly block further processing of authentication/authorization
            // if too many failures have occurred
            if (status.isBlocked()) {
                logger.warn("Blocking authentication attempt from address \"{}\" due to number of authentication failures.", address);
                throw new TranslatableGuacamoleClientTooManyException("Too "
                        + "many failed authentication attempts.",
                        "LOGIN.ERROR_TOO_MANY_ATTEMPTS");
            }

            // Clean up tracking of failures if the address is no longer
            // relevant (all failures are sufficiently old)
            else if (!status.isValid()) {
                logger.debug("Removing address \"{}\" from tracking as there are no recent authentication failures.", address);
                failures.invalidate(address);
            }

        }

    }
Reports that an authentication request has been received, as well as
whether that request is known to have failed. If the associated address
is currently being blocked, an exception will be thrown.

@param credentials
    The credentials associated with the authentication request.

@param failed
    Whether the request is known to have failed. If the status of the
    request is not yet known, this should be false.

@throws GuacamoleException
    If the authentication request is being blocked due to brute force
    prevention rules.
extensions/guacamole-auth-ban/src/main/java/org/apache/guacamole/auth/ban/status/InMemoryAuthenticationFailureTracker.java