...
Each subproject creates a JAR or WAR file. The first project is cas-server-core and it builds a JAR file containing about 95% or more of all the CAS code. It has to be built first because all the other projects depend on it. After that, there are projects to create optional components that you may or may not choose to use.
Building the WAR
The CAS WAR that you actually run in the Web server is built in two steps in two Maven projects.
Apereo distributes a project called cas-server-webapp to create an initial template WAR file. This WAR is not particularly useful, but it contains at least a starter version of all the Spring XML used to configure CAS and many CSS, JSP, and HTML pages. It also contains a WEB-INF/lib with the basic JAR libraries needed by a CAS system. This unmodified Apereo WAR file is a "template" that Yale modifies or updates to create our final WAR.
Although you can modify the cas-server-webapp project directly, this results in a directory with a mixture of Apereo files and Yale files, and the next time you get a new CAS release from Apereo you have to sift through them to find out which ones have been changed by Apereo.
Apereo recommends using the WAR Overlay feature of Maven. Yale creates a second WAR project called cas-server-yale-webapp that contains only the files that Yale has changed or added. Generally the WAR Overlay includes:
- Yale Java source for Spring Beans that are slightly modified versions of standard Apereo beans.
- Yale "branded" look and feel (CSS, JSP, HTML).
- Spring XML to configure Apereo options that Yale has selected and a few Yale additions.
- A pom.xml file with dependency statements for Apereo optional and Yale additional JAR files referenced by the Spring XML that will be added to WEB-INF/lib.
Maven realizes this is a WAR Overlay project because the cas-server-webapp WAR is referenced as a dependency. Since one WAR cannot be included inside another, this is a Maven idiom that everything in this project modifies or adds files to the cas-server-webapp template WAR file. Files in the Yale Overlay project replace files with the same name in the Template cas-server-webapp project. Files with new names are added to the output WAR. All the XML, CSS, HTML, JSP, and other files in the template WAR that do not appear in the Yale WAR Overlay project are simply copied to the output WAR as isWith CAS 3 Yale starts with the Apereo CAS source directory tree and adds new subproject subdirectories for the Yale added code.
Starting with CAS 4, Yale creates a separate Yale-CAS project directory containing only our subprojects, but we copy the Apereo parent pom.xml file from the distributed Apereo Source distribution and modify it so it becomes a Yale specific file.
Building the WAR
Before you build the WAR, you have to build all the JAR files it will contain. Apereo JAR files can be downloaded by Maven from the Internet so they do not have to be rebuilt. Yale JAR files, and any Apereo JAR files that Yale decides to modify, have be be locally compiled and stored. Yale new and modified artifacts always have a Yale specific Version ID that distinguishes them from the Apereo CAS artifacts.
The CAS WAR that you actually run in the Web server is built in two steps in two Maven projects.
Apereo distributes a project called cas-server-webapp to create an initial template WAR file. This WAR is not particularly useful, but it contains at least a starter version of all the Spring XML used to configure CAS and many CSS, JSP, and HTML pages. It also contains a WEB-INF/lib with the basic JAR libraries needed by a CAS system. This unmodified Apereo WAR file is a "template" that Yale modifies or updates to create our final WAR.
Although you can modify the cas-server-webapp project directly, this results in a directory with a mixture of Apereo files and Yale files, and the next time you get a new CAS release from Apereo you have to sift through them to find out which ones have been changed by Apereo.
Apereo recommends using the WAR Overlay feature of Maven. Yale creates a second WAR project called cas-server-yale-webapp that contains only the files that Yale has changed or added. Generally the WAR Overlay includes:
- Yale Java source for Spring Beans that are slightly modified versions of standard Apereo beans.
- Yale "branded" look and feel (CSS, JSP, HTML).
- Spring XML to configure CAS options that Yale has selected and a few Yale additions.
- A pom.xml file with dependency statements for Apereo optional and Yale additional JAR files referenced by the Spring XML that will be added to WEB-INF/lib.
A normal WAR project simply takes all the files in the project and uses them to build a WAR. A WAR Overlay project, however, starts with a template WAR that has already been built. Maven knows that it is working with a WAR Overlay project when it discovers that the first <dependency> in the POM is a file of type "war". Since one WAR cannot contain another WAR inside it, Maven knows that it is supposed to start with the template (dependency) WAR and update it by replacing or adding files from this project to build the output WAR file.
The Template WAR built by cas-server-webapp contains most of the Spring XML configuration, an initial set of CSS, HTML, and JSP files, and almost all the JAR files needed by CAS in its WEB-INF/lib. It also contains the cas-server-core JAR because which has 95% of all the CAS code.
The Yale WAR Overlay project replaces the CSS, JS, HTML, and JSP files associated with the CAS login function to provide the Yale "look and feel" of the CAS login page that everyone expects. It also replaces some of the subsequent confirmation or error pages to also have the same look.
Yale has selected several CAS optional modules. We use cas-server-support-ldap because we authenticate user passwords to AD using LDAP protocol, and cas-server-integration-ehcache because we use ehcache to replicate tickets between CAS servers. These optional JAR files will have been built by Apereo and are available as Maven artifacts, but they were not included in the cas-server-webapp template because they are optional. So the Yale WAR Overly has to add these JAR files to its list of dependencies and configure these options in new or modified Spring XML files. We also must include the JAR files build by the two Yale projects.
While the WAR Overlay process provides a way to update, replace, or add files, it does not provide any way to delete files you no longer want. However, the Maven WAR building plugin builds a WAR using the maven-war-plugin which can be configured in the WAR Overlay POM with an "exclude" list of files to remove from the template POM file. One configuration option is the <packagingExcludes> list that lists a file (or wildcard set of files) in the Template WAR that are to be removed instead of being copied to the output WAR. There are two cases where this is used:
- Apereo builds CAS for Tomcat, which provides only a limited number of libraries to the applications, and so it will run on older versions of Java. Yale runs CAS under JBoss which provides a larger number of libraries standard, and JBoss expects later versions of Java. JBoss complains at startup when it finds that a WAR file contains JARs in its WEB-INF/lib that conflict with libraries built into JBoss. We exclude the libraries that JBoss or modern Java provide by default.
- Sometimes Apereo code depends on a slightly older version of a JAR file, but Yale code requires a slightly newer version of the JAR. If Some JAR files used by the cas-server-webapp project to build a WAR that will run in Tomcat are inappropriate for JBoss. JBoss provides its own versions of some JAR files, so the JAR file provided by the application should be deleted.
- If you build everything with a single Maven environment then Maven will ensure that the latest required version of any given JAR file is used by all modules. However, the cas-server-webapp WAR file is built by Apereo with the latest version of all the libraries it uses. Yale has a few of its own projects that it builds in its own Maven environment, and every so often Yale will use a later version of a JAR file than Apereo required. So if cas-server-webapp had a dependency on 1.2.3 of some JAR file and Yale depends on 1.2.4, then the normal WAR Overlay process would copy both versions of the JAR file (1.2.3 and also 1.2.4) to the output WEB-INF/lib. So we add an Exclude statement a packagingExcludes statement in the WAR Overly POM to delete the old version (1.2.3) to make sure the only version we want is the one we getof the JAR in the WAR we are going to run at Yale has only the version of the library we want to use.
Version Numbers and Project Structure
...
- The "service=" parameter value on the CAS login has to exactly match the value of the same parameter on the validate, serviceValidate, or samlValidate request. There is a difference of option about how carefully they have to match. The JASIG code matched the entire string excluding JSESSIONID if it was present. Yale believes that the entire query string (everything after the "?") should be excluded, and maybe the match should stop with context (https://servername/context/stuff-to-be-ingnored). This changes the substrings used in the equals() test.
- In the Login WebFlow logic Apereo saves the generated TGTID in a "request" scoped variable between the userid/password form and the CASTGC cookie generation, but when we insert the Duo second login screen all "request" scoped variables are lost. We had to copy it to "flow" scope during the display of the Duo form.
- When you are having a CAS problem, you may want to insert additional logging. For example, if the validate request is failing you may want to print out the exact service= strings being compared and the point at which they differ.
- Apereo defaults all registered services to be able to Proxy, but it seems better if the default is that they cannot Proxy unless you explicitly authorize it. This involves changing the default value for allowedToProxy in AbstractRegisteredService.java from "true" to "false".
- AbstractTicket is a Serializable class, but Apereo source forgot to give it a VersionUID. As a result, every time you deploy a new version of cas-server-core you have to "cold start" CAS by wiping out all the current tickets. You should only have to do that if you actually have changed the Ticket classes, not just because you recompiled the library to change something that has nothing to do with Tickets.
- Yale does not use Single Sign-Out, but code in TicketGrantingTicketImpl added to support that option has a very small but non-zero chance of throwing a ConcurrentAccessException and possibly screwing CAS up. Since we don't need it, Yale might just comment out the statement that causes the problem.
...