Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: Migrated to Confluence 5.3

Motivation

...

Code Block
<?xml version="1.0" encoding="UTF-8"?>
<flow xmlns="http://www.springframework.org/schema/webflow"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="
              http://www.springframework.org/schema/webflow
              http://www.springframework.org/schema/webflow/spring-webflow-1.0.xsd">

 

<start-state idref="provideLoginTicketToRemoteRequestor" />

<action-state id="provideLoginTicketToRemoteRequestor">
<action bean="provideLoginTicketToRemoteRequestorAction" />
<transition on="loginTicketRequested" to="viewRedirectToRequestor" />
<transition on="continue" to="automaticCookiePathSetter" />
</action-state>

<view-state id="viewRedirectToRequestor" view="bmRedirectToRequestorView">
<transition on="submit" to="bindAndValidate" />
</view-state>

Code Block
<action-state id="automaticCookiePathSetter">
        <action bean="automaticCookiePathSetterAction" />
        <transition on="success"
            to="ticketGrantingTicketExistsCheckAction" />
    </action-state>

    <action-state id="ticketGrantingTicketExistsCheckAction">
        <action bean="ticketGrantingTicketExistsAction" />
        <transition on="ticketGrantingTicketExists"
            to="hasServiceCheck" />
        <transition on="noTicketGrantingTicketExists"
            to="gatewayRequestCheck" />
    </action-state>

    <action-state id="gatewayRequestCheck">
        <action bean="gatewayRequestCheckAction" />
        <transition on="gateway" to="redirect" />
        <transition on="authenticationRequired" to="viewLoginForm" />
    </action-state>

    <action-state id="hasServiceCheck">
        <action bean="hasServiceCheckAction" />
        <transition on="authenticatedButNoService"
            to="viewGenericLoginSuccess" />
        <transition on="hasService" to="renewRequestCheck" />
    </action-state>

    <action-state id="renewRequestCheck">
        <action bean="renewRequestCheckAction" />
        <transition on="authenticationRequired" to="viewLoginForm" />
        <transition on="generateServiceTicket"
            to="generateServiceTicket" />
    </action-state>

    <!--
        <action-state id="startAuthenticate">
        <action bean="x509Check" />
        <transition on="success" to="sendTicketGrantingTicket" />
        <transition on="error" to="viewLoginForm" />
        </action-state>
    -->
    <view-state id="viewLoginForm" view="casLoginView">
        <transition on="submit" to="bindAndValidate" />
    </view-state>

    <action-state id="bindAndValidate">
        <action bean="authenticationViaFormAction" />
        <transition on="success" to="submit" />
        <transition on="error" to="viewLoginForm" />
    </action-state>

    <action-state id="submit">
        <action bean="authenticationViaFormAction" method="submit" />
        <transition on="warn" to="warn" />
        <transition on="success" to="sendTicketGrantingTicket" />
        <transition on="error" to="viewLoginForm" />

 

<transition on="errorForRemoteRequestor" to="viewRedirectToRequestor" />

Code Block
</action-state>

    <action-state id="sendTicketGrantingTicket">
        <action bean="sendTicketGrantingTicketAction" />
        <transition on="success" to="serviceCheck" />
    </action-state>

    <action-state id="serviceCheck">
        <action bean="hasServiceCheckAction" />
        <transition on="authenticatedButNoService"
            to="viewGenericLoginSuccess" />
        <transition on="hasService" to="generateServiceTicket" />
    </action-state>

    <action-state id="generateServiceTicket">
        <action bean="generateServiceTicketAction" />
        <transition on="success" to="warn" />
        <transition on="error" to="viewLoginForm" />
        <transition on="gateway" to="redirect" />
    </action-state>

    <!--
        The "warn" action makes the determination of whether to redirect directly to the requested
        service or display the "confirmation" page to go back to the server.
    -->
    <action-state id="warn">
        <action bean="warnAction" />
        <transition on="redirect" to="redirect" />
        <transition on="warn" to="showWarningView" />
    </action-state>

    <!--
        the "viewGenericLogin" is the end state for when a user attempts to login without coming directly from a service.
        They have only initialized their single-sign on session.
    -->
    <end-state id="viewGenericLoginSuccess"
        view="casLoginGenericSuccessView" />


    <!--
        The "showWarningView" end state is the end state for when the user has requested privacy settings (to be "warned") to be turned on.  It delegates to a
        view defines in default_views.properties that display the "Please click here to go to the service." message.
    -->
    <end-state id="showWarningView" view="casLoginConfirmView" />

    <!--
        The "redirect" end state allows CAS to properly end the workflow while still redirecting
        the user back to the service required.
    -->
    <end-state id="redirect"
        view="externalRedirect:${externalContext.requestParameterMap['service']}${requestScope.ticket == null ? '' : (externalContext.requestParameterMap['service'].indexOf('?') != -1 ? '&amp;' : '?') + 'ticket=' + requestScope.ticket}" />

    <global-transitions>
        <transition to="viewServiceErrorView"
            on-exception="org.jasig.cas.services.UnauthorizedServiceException" />
    </global-transitions>
</flow>

...

Code Block
[...]         try {
            final String ticketGrantingTicketId = this.centralAuthenticationService
                .createTicketGrantingTicket(credentials);
            ContextUtils.addAttribute(context,
                AbstractLoginAction.REQUEST_ATTRIBUTE_TICKET_GRANTING_TICKET,
                ticketGrantingTicketId);
            setWarningCookie(response, warn);
            return success();
        } catch (final TicketException e) {
            populateErrorsInstance(context, e);

            // START: ChangesBusinessMart: check, whether the posting has been sent from a remote server
            String myServerName = request.getLocalName();
            String referrer = request.getParameter("login-at");
            if (referrer != null && referrer.indexOf(myServerName) == -1) {
                return result("errorForRemoteRequestor");
            }

Code Block
return error();
        }
[...]

...

Code Block
package de.businessmart.sso.cas.flow;

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

import org.jasig.cas.web.flow.util.ContextUtils;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.webflow.action.AbstractAction;
import org.springframework.webflow.core.collection.MutableAttributeMap;
import org.springframework.webflow.execution.Event;
import org.springframework.webflow.execution.RequestContext;

import de.businessmart.sso.cas.CasUtility;

/**
 * Opens up the CAS web flow to allow external retrieval of a login ticket.
 * @author konrad.wulf
 *
 */
public class ProvideLoginTicketToRemoteRequestorAction extends AbstractAction
{

	@Override
	protected Event doExecute(RequestContext context) throws Exception
	{
		final HttpServletRequest request = ContextUtils.getHttpServletRequest(context);

		if (request.getParameter("get-lt") != null && request.getParameter("get-lt").equalsIgnoreCase("true")) {
			return result("loginTicketRequested");
		}
		return result("continue");
	}

}

viewRedirectToRequestor actually does the redirects to the referrer:

Code Block
<%@page import="de.businessmart.sso.cas.CasUtility"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="spring" uri="http://www.springframework.org/tags" %>
<% String separator = "";
String referrer = request.getHeader("Referer");
referrer = CasUtility.resetUrl(referrer);
if (referrer != null && referrer.length() > 0) {
    separator =(referrer.indexOf("?") > -1)? "&" : "?"; %>
<html>
    <head>
        <script>
               var redirectURL = "<%= referrer + separator %>lt=${flowExecutionKey}";
        <spring:hasBindErrors name="credentials">
            redirectURL += '&error_message=' + encodeURIComponent ('<c:forEach var="error" items="${errors.allErrors}"><spring:message code="${error.code}" text="${error.defaultMessage}" /></c:forEach>');
        </spring:hasBindErrors>
            window.location.href = redirectURL;
       </script>
    </head>
    <body></body>
</html><%
}
else
{
    out.print("You better know what to do here.");
} %>

...