Apereo CAS presents itself as a multilingual platform supporting protocols such as CAS, SAML2, OAuth2, and OpenID Connect. Support and functionality for each protocol are designed and implemented using a plugin model where each protocol effectively becomes a client of the CAS server, handing off matters of authentication and workflows, and eventually then takes back control to build the appropriate response using its specific bindings, parameters, payload and security requirements. A blog post on how this model works can be found here or here.
This post specifically focuses on the SAML2 identity provider plugin in CAS and how it receives, tracks, and manages authentication requests in single-node and multi-node environments. Our starting position is as follows:
6.3.x
11
By default, a SAML2 authentication request is stored in the servlet container’s HTTP session. Whether you’re using an embedded or external servlet container, the key requirement is to make sure the session timeout policy is long and flexible enough to handle scenarios where the login sequence may be delayed. The delay could be caused by the user taking time to provide input or could be caused by an external system connected to CAS that is not as responsive.
In the event that a SAML2 authentication request cannot be found in the appropriate session container, you might see the following error messages pop up:
java.lang.IllegalArgumentException: SAML request could not be determined from the authentication request
at AbstractSamlIdPProfileHandlerController.retrieveSamlAuthenticationRequestFromHttpRequest(AbstractSamlIdPProfileHandlerController.java:155)
at SSOSamlIdPProfileCallbackHandlerController.handleCallbackProfileRequest(SSOSamlIdPProfileCallbackHandlerController.java:88)
at GeneratedMethodAccessor341.invoke(Unknown Source)
at DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
...
This issue can generally be duplicated using the following sequence:
So, the issue has to do with the fact that:
X + 1
seconds, exceeding that timeout window.A good initial change would be to adjust the session timeout in the CAS configuration. Note that this change is only applicable if you are using an embedded servlet container with CAS, regardless of its type:
server.servlet.session.timeout=PT300S
The solution here very much depends on the time of the external servlet container. For instance, Apache Tomcat generally has a session timeout of 30 minutes, which might be more than sufficient to prevent this type of error. Nonetheless, the session timeout can be adjusted by modifying the Apache Tomcat’s web.xml
file typically at /opt/tomcat/conf/web.xml
:
<session-config>
<!-- Value is set in minutes. -->
<session-timeout>5</session-timeout>
</session-config>
If you have multiple CAS servers deployed behind a load balancer or a proxy, you generally need to make sure Sticky Sessions are turned on and configured at the load balancer level, in addition to carefully managing the session timeouts. Alternatively, you may force force the CAS server to handle session replication itself via the ticket registry using cas.authn.saml-idp.replicate-sessions=true
.
If you have questions about the contents and the topic of this blog post, or if you need additional guidance and support, feel free to send us a note and ask about consulting and support services.
I hope this review was of some help to you and I am sure that both this post as well as the functionality it attempts to explain can be improved in any number of ways. Please feel free to engage and contribute as best as you can.
Happy Coding,
Monday-Friday
9am-6pm, Central European Time
7am-1pm, U.S. Eastern Time
Monday-Friday
9am-6pm, Central European Time