/* * Licensed to Jasig under one or more contributor license * agreements. See the NOTICE file distributed with this work * for additional information regarding copyright ownership. * Jasig licenses this file to you under the Apache License, * Version 2.0 (the "License"); you may not use this file * except in compliance with the License. You may obtain a * copy of the License at the following location: * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.jasig.cas.login; import java.io.IOException; import com.meterware.httpunit.WebResponse; /** * Helper class for accomplishing CAS login, a common task of compatibility tests. * * @since 3.0 */ public final class LoginHelper { private LoginHelper() {} /** * Extract a serviceTicket from a CAS 1 ticket validation response. * @param webResponse the web application validation response * @return a String representing the ticket * @throws IOException on IO error reading response * @throws RuntimeException on some parse failures */ public static String serviceTicketFromResponse(final WebResponse webResponse) throws IOException { String serviceTicket; // now we need to extract the service ticket. // in a baseline CAS 2.x distribution return to the service is accomplished by // JavaScript redirect // // CAS 3 accomplishes this differently such that our client has already // followed the redirect to the service, so we'll find the service ticket // on the response URL. String queryString = webResponse.getURL().getQuery(); int ticketIndex = queryString.indexOf("ticket="); if (ticketIndex == -1) { // the ticket wasn't in the response URL. // we're testing for CAS 2.x style JavaScript for redirection, as // recommended in appendix B of the CAS 2 protocol specification // parse the ticket out of the JavaScript String response = webResponse.getText(); int declarationStartsAt = response.indexOf("window.location.href"); // cut off the front of the response up to the beginning of the service URL String responseAfterWindowLocHref = response.substring(declarationStartsAt + "window.location.href12".length()); // The URL might be single or double quoted final int endDoubleQuoteIndex = responseAfterWindowLocHref.indexOf("\""); final int endSingleQuoteIndex = responseAfterWindowLocHref.indexOf("\'"); // we will set this variable to be the index of the first ' or " character int endQuoteIndex = 0; if (endDoubleQuoteIndex == -1 && endSingleQuoteIndex == -1) { throw new RuntimeException("Failed parsing a service ticket from the response:" + response); } else if (endDoubleQuoteIndex > -1 && (endDoubleQuoteIndex < endSingleQuoteIndex || endSingleQuoteIndex == -1)) { endQuoteIndex = endDoubleQuoteIndex; } else { endQuoteIndex = endSingleQuoteIndex; } int ticketEqualsIndex = responseAfterWindowLocHref.indexOf("ticket="); serviceTicket = responseAfterWindowLocHref.substring(ticketEqualsIndex + "ticket=".length(), endQuoteIndex); } else { // service ticket was found on query String, parse it from there // TODO Is this type of redirection compatible? // Does it address all the issues that CAS2 JavaScript redirection // was intended to address? serviceTicket = queryString.substring(ticketIndex + "ticket=".length(), queryString.length()); } return serviceTicket; } }