Should the need arise to replace CAS, it may be possible to do so and "fool" all applications which use the LoginFilter.
How would you do this?
To best describe the technique:
- We will assume some kind of authentication proxy sits in front of all applications, which is client to an upstream provider (SAML/Shibboleth or OpenID Connect usually). Usually, an authentication proxy is oauth2_proxy, vouch, or one of the SAML/shibboleth equivalents, either for nginx or apache.
- We will assume that the authentication proxy can set an appropriate header which corresponds to the crowd
- For this example, we will assume that the header is passed along under the REMOTE_USER header by that proxy
- The LoginFilter looks at the last time a session was checked against CAS. We need to ALWAYS update that last checked time for the session to be the time of the request, so that it never attempts a redirect to CAS (We can do this because the proxy is enforcing authentication)
- To spoof the session without recompiling everything - we need to use a Tomcat Valve. Pseudocode below
- Logout would probably be handled at the layer above. Generally speaking, you don't usually logout of the SSO types of applications though.
The CrawlerSessionManagerValve is an example of a valve that is introspecting and handling sessions, but with slightly different goals.
@Override public void invoke(Request request, Response response) throws IOException, ServletException { // Some requests may be trusted, like from other servers // This assumes your proxy is setup to allow those requests // to punch through boolean trustedRequest = isTrustedRequest(request); // Get the remote user, or set it as an empty string String remoteUser = request.getHeader("REMOTE_USER"); if (remoteUser == null){ remoteUser = ""; } if (trustedRequest){ handleTrustedRequest(request); } else { if (!remoteUser.isEmpty()){ spoofAuthenticatedUserSession(request, response); } else { // Untrusted request and/or // Proxy not enforcing login (anonymous us) spoofAnonymousUserSession(request, response); } } getNext().invoke(request, response); }
It should be noted that proxy configuration might need to be adjusted carefully if maintaining anonymous login is desired - especially true for datacat and the like. The valve may also need to be carefully written to handle that.