Vaadin 6 CAS Client

Basic CAS client developed on Vaadin 6.7.5. Only handles authentication (not authorization strategy). Pages which need to have a CAS authentication just have to extend this class.




import java.io.IOException;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.jasig.cas.client.authentication.AttributePrincipal;
import org.jasig.cas.client.validation.Assertion;
import org.jasig.cas.client.validation.Cas20ServiceTicketValidator;
import org.jasig.cas.client.validation.TicketValidationException;

import com.vaadin.Application;
import com.vaadin.terminal.gwt.server.HttpServletRequestListener;


/**
 * Basic CAS authenticated application for Vaadin 6.7.5. <br/>
 * Just import this class into your project <br/>
 * . Your application just has to extend this class<br/>
 * <br/>
 *
 * @author Alexandre de Pellegrin - ESSEC Business School
 *
 */
public class CasAuthenticatedApplication extends Application implements HttpServletRequestListener {

    /** Session key which indicates if the user is already authenticated */
    private static final String SSO_FLAG_AUTHENTICATED = "SSO_FLAG_AUTHENTICATED";

    /** URL parameter to retrieve the CAS service ticket */
    private static final String SSO_TICKET_URL_PARAM = "ticket";

    /**
     * Your CAS server base URL. Don't forget to change it. Ex :
     * https://my_cas_server/cas/"
     */
    public static String SSO_CAS_BASE_URL = "https://my_cas_server/cas/";
    
    @Override
    public void init() {
        // Nothing to do here for CAS authentication
    }

    @Override
    public void onRequestEnd(HttpServletRequest request, HttpServletResponse response) {
        // Nothing to do here for CAS authentication
    }

    @Override
    public void onRequestStart(HttpServletRequest request, HttpServletResponse response) {
        try {
            HttpSession session = request.getSession();
            if (isTicketToValidate(request)) {
                boolean isValidated = validateTicket(request);
                if (isValidated) {
                    reloadPage(request, response);
                    return;
                }
            }
            if (!isAuthenticated(session)) {
                redirectToLoginPage(request, response);
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
    
    

    /**
     * @return true if the user has already been authenticated on the CAS server
     */
    private boolean isAuthenticated(HttpSession session) {
        Object value = session.getAttribute(SSO_FLAG_AUTHENTICATED);
        if (value != null) {
            return true;
        }
        return false;
    }

    /**
     * Redirects to the CAS login page
     */
    private void redirectToLoginPage(HttpServletRequest request, HttpServletResponse response) throws IOException {
        String pageURL = getPagePublicURL(request);
        String redirectURL = getSSOBaseURL() + "/login?service=" + pageURL;
        response.sendRedirect(redirectURL);
    }

    /**
     * Reloads page without the service ticket to avoid multiple submit with the
     * same ticket
     */
    private void reloadPage(HttpServletRequest request, HttpServletResponse response) throws IOException {
        String pageURL = getPagePublicURL(request);
        response.sendRedirect(pageURL);
    }
    
    
    /**
     * @return CAS url
     */
    private String getSSOBaseURL() {
        // TODO : add test for dev/prod auto-switch
        return SSO_CAS_BASE_URL;
    }


    /**
     * @return true if there's a CAS service ticket in the current request
     */
    private boolean isTicketToValidate(HttpServletRequest request) {
        String ticketValue = getTicket(request);
        if (ticketValue != null) {
            return true;
        }
        return false;
    }

    /**
     * @return the current CAS service ticket
     */
    private String getTicket(HttpServletRequest request) {
        return request.getParameter(SSO_TICKET_URL_PARAM);
    }

    /**
     * Validates the CAS service ticket on the CAS server
     */
    private boolean validateTicket(HttpServletRequest request) {
        String ticket = getTicket(request);
        if (ticket == null) {
            return false;
        }
        String ticketValue = ticket.toString();
        String pageURL = getPagePublicURL(request);
        HttpSession session = request.getSession();
        try {
            Cas20ServiceTicketValidator ticketValidator = new Cas20ServiceTicketValidator(getSSOBaseURL());
            Assertion assertion = ticketValidator.validate(ticketValue, pageURL);
            AttributePrincipal principal = assertion.getPrincipal();
            String user = principal.getName();
            session.setAttribute(SSO_FLAG_AUTHENTICATED, Boolean.TRUE);
            // Push authentication user into Vaadin application
            setUser(user);
            return true;
        } catch (TicketValidationException e) {
            session.invalidate();
        }
        return false;
    }

    /**
     * @return the url of this page as seen by the browser
     */
    private String getPagePublicURL(HttpServletRequest request) {
        String requestURL = request.getRequestURL().toString();
        return requestURL;
    }

}