Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / Languages / Java

Simplifying CAS for Security

4.00/5 (1 vote)
17 Jul 2008CPOL1 min read 1  
An article about simplifying CAS for security

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

Java
/*
 * Copyright 2007 The JA-SIG Collaborative. All rights reserved. See license
 * distributed with this file and available online at
 * http://www.uportal.org/license.html
 */
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;

/**
 * Brute-force Service Registry Dao for production use (limited service registry).
 * This class is created for a small number of service registrations that will
 * be Spring configured and managed without the use of the services Web
 * interface.
 *
 * @author David Whitehurst
 * @version $
 * @since 3.1
 *
 */

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() {

    // always load Service Manager application
    registerApplication("Service Manager", "https://localhost:8443/cas/services/**");

    // get registered applications
    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();

            // register application
            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.

XML
<!--
    |
    | This DAO implementation allows for the registration of
    | CAS services at a configuration level.
    | hard coded service registry.
    | The cas/services directory can be removed from /WEB-INF/view/jsp
    | so that UI access to the service manager is completely disabled.
    | The following properties are set as true by default,
    | enabled, allowed to proxy, and SSO.
    |
+ -->

    <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>

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)