CAS documentation has moved over to apereo.github.io/cas, starting with CAS version 4.x. The wiki will no longer be maintained. For the most recent version of the documentation, please refer to the aforementioned link.
Versions prior to CAS 3.3.5, had a simplistic approach to throttling attempts based on IP Addresses. Since CAS 3.3.5, those options have been expanded.
For single node CAS instances, there are two in-memory approaches: One by IP Address, and one by IP Address + username combination.
For multi-node CAS instances there is one option that combines the auditing capabilities of the Inspektr package with the throttling package (and relies on a database).
The throttle feature intercepts attempted logins for an IP or IP+username once the configured failed login threshold per time has been reached. At that point, further logins from that source are intercepted before reaching the CAS service. Once throttle intercept has been activated for an IP or IP/username, it stays active until the count of failed logins decays to less than the threshold. Further valid or invalid login attempts from a throttled source increase the count for each attempt. Decay is performed by repeatedly decrementing a counter of failed logins/further attempts by 1. The rate of decrements is controlled by the repeatInterval parameter specified in the periodicThrottleCleanerTrigger bean (see below, note that this parameter is set in milliseconds). Once the failed login count passes under the failureThreshold value, the throttle is released.
As of version 3.5.0, the behavior of throttling (for both the in-memory and Inspektr approaches) has changed according to . Throttling is now performed based on a rate, the number of failed login attempts allowed per minute. For example, consider a case in Inspektr where failureRangeInSeconds=60 and failureThreshold=10. This leads to a rate of 10 failed attempts per minute, or one every six seconds. The throttler works by maintaining this rate between pairs of login attempts. A throttle flag is set which will block further login attempts if the last two attempts surpassed the threshold rate. Consider the code snippet below which returns the value of the flag.
Failed logins are logged in your Inspektr audit table, if Inspektr is configured, and/or in your cas.log file.Once failed logins reach the threshold you configure, throttling is logged in your cas.log file as:
WARN [org.jasig.cas.web.support.InMemoryThrottledSubmissionByIpAddressHandlerInterceptorAdapter] - *** Possible Hacking Attempt from [x.x.x.x]. More than yy failed login attempts within zz seconds.
Once throttling has started for an IP, further attempts to log in are intercepted before they get to the CAS application and logged as 403 errors in your webserver access logs. If you're not fronting your CAS Tomcat server with Apache httpd, you may need to configure the access log "Valve" to get standard access logs in Tomcat (see http://tomcat.apache.org/tomcat-6.0-doc/config/valve.html).
tracks an issue that breaks the in-memory approach specifically for CAS versions 3.4 and higher. For this reason, the in-memory approach is only illustrated below for a prior CAS version.
As you've already done the work for configuring Inspektr, this method merely requires you to configure the new interceptor and give it a DataSource and an AuditTrailManager instance.
No proper "loginController" is defined in cas-servlet.xml, unlike in earlier versions. All you need to do is add the throttleInterceptor to the FlowHandlerMapping.
Example of Inspektr
Note, you should configure Inspektr per the instructions. You may wish to expand the default client IP and server IP table space to account for IPv6.
Allow inspektr to record the real client IP address in the web.xml file:
<filter> <filter-name>CAS Client Info Logging Filter</filter-name> <filter-class>com.github.inspektr.common.web.ClientInfoThreadLocalFilter</filter-class> <!-- set this parameter to get real Address from HTTP HEADER when we use Load-balance --> <init-param> <param-name>alternativeIpAddressHeader</param-name> <param-value>X-Forwarded-For</param-value> </init-param> </filter>