@Override
    public boolean exceedsThreshold(final HttpServletRequest request) {
        val clientInfo = ClientInfoHolder.getClientInfo();
        val remoteAddress = clientInfo.getClientIpAddress();
        val throttle = getConfigurationContext().getCasProperties().getAuthn().getThrottle();
        try (val keys = redisTemplate.scan(RedisAuditTrailManager.CAS_AUDIT_CONTEXT_PREFIX + '*', this.scanCount)) {
            val username = getUsernameParameterFromRequest(request);
            val failures = keys
                .map((Function<String, BoundValueOperations>) redisTemplate::boundValueOps)
                .map(BoundValueOperations::get)
                .map(AuditActionContext.class::cast)
                .filter(audit ->
                    audit.getPrincipal().equalsIgnoreCase(username)
                        && audit.getClientInfo().getClientIpAddress().equalsIgnoreCase(remoteAddress)
                        && audit.getActionPerformed().equalsIgnoreCase(throttle.getFailure().getCode())
                        && audit.getApplicationCode().equalsIgnoreCase(throttle.getCore().getAppCode())
                        && audit.getWhenActionWasPerformed().isAfter(getFailureInRangeCutOffDate()))
                .sorted(Comparator.comparing(AuditActionContext::getWhenActionWasPerformed).reversed())
                .limit(2)
                .map(this::toThrottledSubmission)
                .collect(Collectors.toList());
            return calculateFailureThresholdRateAndCompare(failures);
        }
    }
Works in conjunction with a redis database to
block attempts to dictionary attack users.

@author Misagh Moayyed
@since 6.1.0
support/cas-server-support-throttle-redis/src/main/java/org/apereo/cas/web/support/RedisThrottledSubmissionHandlerInterceptorAdapter.java