The CAS Server is a Spring Web Application, but it is designed according to standard layers or functional components that can be plugged into a standard J2EE diagram. There are three main components, each of which can be subdivided into subcomponents.
- The front end is a "Presentation Layer" that handles arriving HTTP requests. In addition to presenting and processing the Login form (containing userid and password), this layer also handles non-interactive forms of login (X.509 Certificates), and the Service Ticket validation and Proxy ticket calls.
- The Business Layer (where J2EE would have EJBs) validates the login (by verifying the userid/password against a backend system such as Kerberos or LDAP), and it creates Tickets including the Login TGT and Service Tickets.
- Tickets are stored in a Ticket Cache. Normally this is just an in-memory collection, although it can be replicated (for clustered failover) or stored in a shared database. Since Tickets can be persisted (even though they frequently aren't) they become Entities in a logical Persistence Layer.
Presentation Layer
CAS 3 uses two different Spring APIs to configure and code the Presentation Layer.
The calls to validate Service Tickets and issue Proxy Tickets are processed by Spring MVC configured in the WEB-INF/cas-servlet.xml file.Spring "Action" Beans are configured that expose a method that receives the Request and Response object of an incoming HTTP operation.
<bean id="serviceValidateController" class="org.jasig.cas.web.ServiceValidateController" p:validationSpecificationClass="org.jasig.cas.validation.Cas20WithoutProxyingValidationSpecification" p:centralAuthenticationService-ref="centralAuthenticationService" p:proxyHandler-ref="proxy20Handler" p:argumentExtractor-ref="casArgumentExtractor" />
Action Beans are essentially Servlets, only with a Spring flavor. Parameters from the request are "bound" (used to set the properties of a bean). The Action Bean is inside the ApplicationContext, so it gets dependency injection. It returns an object (ModelAndView) that identifies the response (typically a JSP page although it can be a View Bean) and provides a Map of data that the JSP EL can use to populate variable fields in the response page.
Each Action Bean is called when the end of a request URL contains a string mapped to the Bean (again in cas-servlet.xml):
<prop key="/serviceValidate"> serviceValidateController </prop>
The "/login" function is mapped to an entirely separate API called Spring WebFlow. WebFlow is a common computer design pattern called a "State Machine" coded as a sequence of XML elements in the WEB-INF/login-webflow.xml file. In some sense, a WebFlow demonstrates how to replace a dozen lines of Java with a hundred lines of considerably more complex XML (but at least you are not coding).
Each state is represented by an XML element that either performs a simple EL test or else calls a Bean method. The result of the test or return value of the method is "success" or "error" and generates a transition (a GOTO) to another state.
<action-state id="startAuthenticate"> <action bean="x509Check" /> <transition on="success" to="sendTicketGrantingTicket" /> <transition on="error" to="viewLoginForm" /> </action-state>
When the login flow gets to this state, it calls a method of the x509Check Bean (which determines if the Request has a valid X.509 Certificate that can be used to login the user). A return of "success" means the user has logged on and proceeds to a state/bean that generates the Ticket Granting Cookie in the response object. An "error" means that there is no certificate, so the normal interactive Login form is displayed.
The flow continues until there is a transition to an "end-state" which either displays a JSP page or else redirects the Browser to another page.
Ideally, the Presentation Layer would be the only component that deals with the Servlet API and its Request, Response, and Session objects. That is certainly possible for userid/password, but certain credentials may be inherently tied to the underlying socket and communications layers.
Business Logic
The Business Logic layer of CAS represents a set of services configured by the WEB-INF/deployerConfigContext.xml file. In a J2EE world, these would be the EJBs.
There is only one service interface exposed by Business Logic. It is the CentralAuthenticationService interface that exposes methods to create a TicketGrantingTicket (by logging on a user if the credentials presented are valid), create and validate ServiceTickets, and log the user off. All the other components provide support services to this interface.
The most important support service, and the most important configuration option for CAS, is the Bean implementing the AuthenticationManager interface configured to id "authenticationManager" in deployerConfigContext.xml.