Introduction
During my implementation of the Central Authentication Service (CAS), my client did not want to support the service registry portion of the CAS WAR. The CAS Web application has a few JSP pages to provide a UI for the registry of applications or services that will be CAS supported. Our Security Chief did not want to provide any administrative access in the application that would verify our users and credentials for the enterprise. Originally we used the service manager and because Spring webflow is used, the directory at /services could just be removed once the applications were registered. This was clean and did not present any error messages. In fact, if the service URL was called, the login page was presented. Perfect right? Not really.
My CAS WAR has been modified now to support the removal of the Service Manager application altogether. Prior to these modifications, the service registry was being persisted to the file system using the HSQL database and CAS provided persistence classes. I have developed a simpler mechanism for registering the service applications by configuring them in a Spring context file and loading them into memory whenever CAS is deployed. This is accomplished using a custom implementation of ServiceRegistryDao
. The source for this custom file is provided here.
The Code
package org.jasig.cas.services;
import java.util.*;
import org.jasig.cas.util.DefaultLongNumericGenerator;
import org.jasig.cas.util.LongNumericGenerator;
import org.jasig.cas.util.annotation.NotNull;
public final class EasyServiceRegistryDaoImpl implements ServiceRegistryDao {
@NotNull
private List<registeredservice /> registeredServices = new ArrayList<registeredservice />();
private LongNumericGenerator generator = new DefaultLongNumericGenerator();
private Map serviceMap = new HashMap();
public boolean delete(RegisteredService registeredService) {
return this.registeredServices.remove(registeredService);
}
public RegisteredService findServiceById(final long id) {
for (final RegisteredService r : this.registeredServices) {
if (r.getId() == id) {
return r;
}
}
return null;
}
public List<registeredservice /> load() {
registerApplication("Service Manager", "https://localhost:8443/cas/services/**");
addRegisteredApplications();
return this.registeredServices;
}
public RegisteredService save(final RegisteredService registeredService) {
if (registeredService.getId() == -1) {
((RegisteredServiceImpl) registeredService).setId
(this.generator.getNextLong());
}
this.registeredServices.remove(registeredService);
this.registeredServices.add(registeredService);
return registeredService;
}
public void setRegisteredServices(final List<registeredservice /> registeredServices) {
this.registeredServices = registeredServices;
}
public void setServiceMap(Map serviceMap) {
this.serviceMap = serviceMap;
}
private void addRegisteredApplications() {
for (Iterator it=serviceMap.entrySet().iterator(); it.hasNext(); ) {
Map.Entry entry = (Map.Entry)it.next();
String key = (String) entry.getKey();
String value = (String) entry.getValue();
registerApplication(key, value);
}
}
private void registerApplication(String name, String urlPattern) {
final RegisteredServiceImpl r = new RegisteredServiceImpl();
r.setName(name);
r.setDescription("This is the description for the " + name);
r.setServiceId(urlPattern);
r.setAllowedToProxy(true);
r.setAnonymousAccess(false);
r.setEnabled(true);
r.setSsoEnabled(true);
r.setId(this.generator.getNextLong());
if (r.getId() == -1) {
((RegisteredServiceImpl) r).setId(this.generator.getNextLong());
}
this.registeredServices.remove(r);
this.registeredServices.add(r);
}
}
Registering services for CAS is very easy now. In the service registry section of WEB-INF/deployerConfigContext.xml, the services can be added with just a name and the URL. Remember that the URL uses the Apache regular expression syntax.
<bean
id="serviceRegistryDao"
class="org.jasig.cas.services.EasyServiceRegistryDaoImpl">
<property name="serviceMap">
<map>
<entry key="Test Application" value="http://localhost:8080/test1/**" />
</map>
</property>
</bean>