Merge pull request #40 from mmoayyed/CASC-180

CASC-180: Fix the issue with casting to http url connections and provide...
This commit is contained in:
Misagh Moayyed 2013-03-11 13:35:54 -07:00
commit 089fca4ca4
12 changed files with 58 additions and 65 deletions

View File

@ -30,7 +30,6 @@ import java.util.Map;
* Concrete implementation of the AttributePrincipal interface.
*
* @author Scott Battaglia
* @version $Revision$ $Date$
* @since 3.1
*/
public class AttributePrincipalImpl extends SimplePrincipal implements AttributePrincipal {
@ -80,7 +79,7 @@ public class AttributePrincipalImpl extends SimplePrincipal implements Attribute
}
/**
* Constructs a new principal witht he supplied name, attributes, and proxying capabilities.
* Constructs a new principal with the supplied name, attributes, and proxying capabilities.
*
* @param name the unique identifier for the principal.
* @param attributes the key/value pairs for this principal.

View File

@ -18,12 +18,15 @@
*/
package org.jasig.cas.client.proxy;
import org.jasig.cas.client.ssl.HttpURLConnectionFactory;
import org.jasig.cas.client.util.CommonUtils;
import org.jasig.cas.client.util.XmlUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.UnsupportedEncodingException;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLEncoder;
/**
@ -43,7 +46,7 @@ public final class Cas20ProxyRetriever implements ProxyRetriever {
/** Unique Id for serialization. */
private static final long serialVersionUID = 560409469568911791L;
/**
/**
* Instance of Commons Logging.
*/
private final Logger logger = LoggerFactory.getLogger(this.getClass());
@ -55,39 +58,45 @@ public final class Cas20ProxyRetriever implements ProxyRetriever {
private final String encoding;
/** Url connection factory to use when communicating with the server **/
private final HttpURLConnectionFactory urlConnectionFactory;
/**
* Main Constructor.
*
* @param casServerUrl the URL to the CAS server (i.e. http://localhost/cas/)
* @param encoding the encoding to use.
* @param urlFactory url connection factory use when retrieving proxy responses from the server
*/
public Cas20ProxyRetriever(final String casServerUrl, final String encoding) {
public Cas20ProxyRetriever(final String casServerUrl, final String encoding, final HttpURLConnectionFactory urlFactory) {
CommonUtils.assertNotNull(casServerUrl, "casServerUrl cannot be null.");
this.casServerUrl = casServerUrl;
this.encoding = encoding;
this.urlConnectionFactory = urlFactory;
}
public String getProxyTicketIdFor(final String proxyGrantingTicketId,
final String targetService) {
final String url = constructUrl(proxyGrantingTicketId, targetService);
final String response = CommonUtils.getResponseFromServer(url, this.encoding);
public String getProxyTicketIdFor(final String proxyGrantingTicketId, final String targetService) {
CommonUtils.assertNotNull(proxyGrantingTicketId, "proxyGrantingTicketId cannot be null.");
CommonUtils.assertNotNull(targetService, "targetService cannot be null.");
final URL url = constructUrl(proxyGrantingTicketId, targetService);
final String response = CommonUtils.getResponseFromServer(url, this.urlConnectionFactory, this.encoding);
final String error = XmlUtils.getTextForElement(response, "proxyFailure");
if (CommonUtils.isNotEmpty(error)) {
logger.debug(error);
return null;
}
return XmlUtils.getTextForElement(response, "proxyTicket");
}
private String constructUrl(final String proxyGrantingTicketId, final String targetService) {
private URL constructUrl(final String proxyGrantingTicketId, final String targetService) {
try {
return this.casServerUrl + (this.casServerUrl.endsWith("/") ? "" : "/") + "proxy" + "?pgt="
+ proxyGrantingTicketId + "&targetService="
+ URLEncoder.encode(targetService, "UTF-8");
} catch (final UnsupportedEncodingException e) {
return new URL(this.casServerUrl + (this.casServerUrl.endsWith("/") ? "" : "/") + "proxy"
+ "?pgt=" + proxyGrantingTicketId
+ "&targetService=" + URLEncoder.encode(targetService, "UTF-8"));
} catch (final Exception e) {
throw new RuntimeException(e);
}
}

View File

@ -18,6 +18,7 @@
*/
package org.jasig.cas.client.ssl;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;
@ -27,7 +28,7 @@ import java.net.URLConnection;
* @author Misagh Moayyed
* @since 3.3
*/
public interface URLConnectionFactory {
public interface HttpURLConnectionFactory {
/**
* Receives a {@link URLConnection} instance typically as a result of a {@link URL}
@ -36,9 +37,9 @@ public interface URLConnectionFactory {
* to accommodate method chaining.
*
* @param url The url connection that needs to be configured
* @return The configured {@link URLConnection} instance
* @return The configured {@link HttpURLConnection} instance
*
* @see {@link HttpsURLConnectionFactory}
*/
URLConnection getURLConnection(final URLConnection url);
HttpURLConnection buildHttpURLConnection(final URLConnection url);
}

View File

@ -2,6 +2,7 @@ package org.jasig.cas.client.ssl;
import java.io.FileInputStream;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URLConnection;
import java.security.KeyStore;
import java.util.Properties;
@ -17,7 +18,7 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* An implementation of the {@link URLConnectionFactory} whose responsible to configure
* An implementation of the {@link HttpURLConnectionFactory} whose responsible to configure
* the underlying <i>https</i> connection, if needed, with a given hostname and SSL socket factory based on the
* configuration provided.
*
@ -26,7 +27,7 @@ import org.slf4j.LoggerFactory;
* @see #setHostnameVerifier(HostnameVerifier)
* @see #setSSLConfiguration(Properties)
*/
public final class HttpsURLConnectionFactory implements URLConnectionFactory {
public final class HttpsURLConnectionFactory implements HttpURLConnectionFactory {
private static final Logger LOGGER = LoggerFactory.getLogger(HttpsURLConnectionFactory.class);
@ -63,7 +64,7 @@ public final class HttpsURLConnectionFactory implements URLConnectionFactory {
this.hostnameVerifier = verifier;
}
public URLConnection getURLConnection(final URLConnection url) {
public HttpURLConnection buildHttpURLConnection(final URLConnection url) {
return this.configureHttpsConnectionIfNeeded(url);
}
@ -74,7 +75,7 @@ public final class HttpsURLConnectionFactory implements URLConnectionFactory {
*
* @param conn the http connection
*/
private URLConnection configureHttpsConnectionIfNeeded(final URLConnection conn) {
private HttpURLConnection configureHttpsConnectionIfNeeded(final URLConnection conn) {
if (conn instanceof HttpsURLConnection) {
final HttpsURLConnection httpsConnection = (HttpsURLConnection) conn;
final SSLSocketFactory socketFactory = this.createSSLSocketFactory();
@ -86,7 +87,7 @@ public final class HttpsURLConnectionFactory implements URLConnectionFactory {
httpsConnection.setHostnameVerifier(this.hostnameVerifier);
}
}
return conn;
return (HttpURLConnection) conn;
}
/**

View File

@ -20,7 +20,7 @@ package org.jasig.cas.client.util;
import org.jasig.cas.client.proxy.ProxyGrantingTicketStorage;
import org.jasig.cas.client.ssl.HttpsURLConnectionFactory;
import org.jasig.cas.client.ssl.URLConnectionFactory;
import org.jasig.cas.client.ssl.HttpURLConnectionFactory;
import org.jasig.cas.client.validation.ProxyList;
import org.jasig.cas.client.validation.ProxyListEditor;
import org.slf4j.Logger;
@ -329,11 +329,11 @@ public final class CommonUtils {
* @param encoding the encoding to use.
* @return the response.
*/
public static String getResponseFromServer(final URL constructedUrl, final URLConnectionFactory factory, final String encoding) {
public static String getResponseFromServer(final URL constructedUrl, final HttpURLConnectionFactory factory, final String encoding) {
URLConnection conn = null;
HttpURLConnection conn = null;
try {
conn = factory.getURLConnection(constructedUrl.openConnection());
conn = factory.buildHttpURLConnection(constructedUrl.openConnection());
final BufferedReader in;
@ -355,26 +355,10 @@ public final class CommonUtils {
LOGGER.error(e.getMessage(), e);
throw new RuntimeException(e);
} finally {
if (conn != null && conn instanceof HttpURLConnection) {
((HttpURLConnection)conn).disconnect();
if (conn != null) {
conn.disconnect();
}
}
}
/**
* Contacts the remote URL and returns the response.
*
* @param url the url to contact.
* @param encoding the encoding to use.
* @return the response.
*/
public static String getResponseFromServer(final String url, String encoding) {
try {
return getResponseFromServer(new URL(url), new HttpsURLConnectionFactory(), encoding);
} catch (final MalformedURLException e) {
throw new IllegalArgumentException(e);
}
}
public static ProxyList createProxyList(final String proxies) {

View File

@ -19,7 +19,7 @@
package org.jasig.cas.client.validation;
import org.jasig.cas.client.ssl.HttpsURLConnectionFactory;
import org.jasig.cas.client.ssl.URLConnectionFactory;
import org.jasig.cas.client.ssl.HttpURLConnectionFactory;
import org.jasig.cas.client.util.CommonUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -45,7 +45,7 @@ public abstract class AbstractUrlBasedTicketValidator implements TicketValidator
* URLConnection factory instance to use when making validation requests to the CAS server.
* Defaults to {@link HttpsURLConnectionFactory}
*/
private URLConnectionFactory urlConnectionFactory = new HttpsURLConnectionFactory();
private HttpURLConnectionFactory urlConnectionFactory = new HttpsURLConnectionFactory();
/**
* Prefix for the CAS server. Should be everything up to the url endpoint, including the /.
@ -238,11 +238,11 @@ public abstract class AbstractUrlBasedTicketValidator implements TicketValidator
return this.customParameters;
}
protected URLConnectionFactory getURLConnectionFactory() {
protected HttpURLConnectionFactory getURLConnectionFactory() {
return this.urlConnectionFactory;
}
public void setURLConnectionFactory(final URLConnectionFactory urlConnectionFactory) {
public void setURLConnectionFactory(final HttpURLConnectionFactory urlConnectionFactory) {
this.urlConnectionFactory = urlConnectionFactory;
}
}

View File

@ -21,7 +21,7 @@ package org.jasig.cas.client.validation;
import javax.servlet.FilterConfig;
import org.jasig.cas.client.ssl.HttpsURLConnectionFactory;
import org.jasig.cas.client.ssl.URLConnectionFactory;
import org.jasig.cas.client.ssl.HttpURLConnectionFactory;
/**
* Implementation of AbstractTicketValidatorFilter that instanciates a Cas10TicketValidator.
@ -39,7 +39,7 @@ public class Cas10TicketValidationFilter extends AbstractTicketValidationFilter
final Cas10TicketValidator validator = new Cas10TicketValidator(casServerUrlPrefix);
validator.setRenew(parseBoolean(getPropertyFromInitParams(filterConfig, "renew", "false")));
final URLConnectionFactory factory = new HttpsURLConnectionFactory(getHostnameVerifier(filterConfig), getSSLConfig(filterConfig));
final HttpURLConnectionFactory factory = new HttpsURLConnectionFactory(getHostnameVerifier(filterConfig), getSSLConfig(filterConfig));
validator.setURLConnectionFactory(factory);
validator.setEncoding(getPropertyFromInitParams(filterConfig, "encoding", null));

View File

@ -31,7 +31,7 @@ import javax.servlet.http.HttpServletResponse;
import org.jasig.cas.client.proxy.*;
import org.jasig.cas.client.ssl.HttpsURLConnectionFactory;
import org.jasig.cas.client.ssl.URLConnectionFactory;
import org.jasig.cas.client.ssl.HttpURLConnectionFactory;
import org.jasig.cas.client.util.CommonUtils;
import org.jasig.cas.client.util.ReflectUtils;
@ -145,7 +145,11 @@ public class Cas20ProxyReceivingTicketValidationFilter extends AbstractTicketVal
}
validator.setProxyCallbackUrl(getPropertyFromInitParams(filterConfig, "proxyCallbackUrl", null));
validator.setProxyGrantingTicketStorage(this.proxyGrantingTicketStorage);
validator.setProxyRetriever(new Cas20ProxyRetriever(casServerUrlPrefix, getPropertyFromInitParams(filterConfig, "encoding", null)));
final HttpURLConnectionFactory factory = new HttpsURLConnectionFactory(getHostnameVerifier(filterConfig), getSSLConfig(filterConfig));
validator.setURLConnectionFactory(factory);
validator.setProxyRetriever(new Cas20ProxyRetriever(casServerUrlPrefix, getPropertyFromInitParams(filterConfig, "encoding", null), factory));
validator.setRenew(parseBoolean(getPropertyFromInitParams(filterConfig, "renew", "false")));
validator.setEncoding(getPropertyFromInitParams(filterConfig, "encoding", null));
@ -161,9 +165,6 @@ public class Cas20ProxyReceivingTicketValidationFilter extends AbstractTicketVal
}
validator.setCustomParameters(additionalParameters);
final URLConnectionFactory factory = new HttpsURLConnectionFactory(getHostnameVerifier(filterConfig), getSSLConfig(filterConfig));
validator.setURLConnectionFactory(factory);
return validator;
}

View File

@ -25,7 +25,6 @@ import org.jasig.cas.client.proxy.ProxyGrantingTicketStorage;
import org.jasig.cas.client.proxy.ProxyRetriever;
import org.jasig.cas.client.util.CommonUtils;
import org.jasig.cas.client.util.XmlUtils;
import org.w3c.dom.NodeList;
import org.xml.sax.Attributes;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
@ -41,7 +40,6 @@ import java.util.*;
* Implementation of the TicketValidator that will validate Service Tickets in compliance with the CAS 2.
*
* @author Scott Battaglia
* @version $Revision$ $Date$
* @since 3.1
*/
public class Cas20ServiceTicketValidator extends AbstractCasProtocolUrlBasedTicketValidator {
@ -60,10 +58,11 @@ public class Cas20ServiceTicketValidator extends AbstractCasProtocolUrlBasedTick
* CAS server url prefix.
*
* @param casServerUrlPrefix the CAS Server URL prefix.
* @param urlFactory URL connection factory to use when communicating with the server
*/
public Cas20ServiceTicketValidator(final String casServerUrlPrefix) {
super(casServerUrlPrefix);
this.proxyRetriever = new Cas20ProxyRetriever(casServerUrlPrefix, getEncoding());
this.proxyRetriever = new Cas20ProxyRetriever(casServerUrlPrefix, getEncoding(), getURLConnectionFactory());
}
/**

View File

@ -22,7 +22,7 @@ import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import org.jasig.cas.client.ssl.HttpsURLConnectionFactory;
import org.jasig.cas.client.ssl.URLConnectionFactory;
import org.jasig.cas.client.ssl.HttpURLConnectionFactory;
/**
* Implementation of TicketValidationFilter that can instanciate a SAML 1.1 Ticket Validator.
@ -57,7 +57,7 @@ public class Saml11TicketValidationFilter extends AbstractTicketValidationFilter
validator.setTolerance(Long.parseLong(tolerance));
validator.setRenew(parseBoolean(getPropertyFromInitParams(filterConfig, "renew", "false")));
final URLConnectionFactory factory = new HttpsURLConnectionFactory(getHostnameVerifier(filterConfig), getSSLConfig(filterConfig));
final HttpURLConnectionFactory factory = new HttpsURLConnectionFactory(getHostnameVerifier(filterConfig), getSSLConfig(filterConfig));
validator.setURLConnectionFactory(factory);
validator.setEncoding(getPropertyFromInitParams(filterConfig, "encoding", null));

View File

@ -233,7 +233,7 @@ public final class Saml11TicketValidator extends AbstractUrlBasedTicketValidator
BufferedReader in = null;
try {
conn = (HttpURLConnection) this.getURLConnectionFactory().getURLConnection(validationUrl.openConnection());
conn = this.getURLConnectionFactory().buildHttpURLConnection(validationUrl.openConnection());
conn.setRequestMethod("POST");
conn.setRequestProperty("Content-Type", "text/xml");
conn.setRequestProperty("Content-Length", Integer.toString(MESSAGE_TO_SEND.length()));

View File

@ -22,7 +22,6 @@ import org.jasig.cas.client.PublicTestHttpServer;
import org.jasig.cas.client.proxy.ProxyGrantingTicketStorage;
import org.jasig.cas.client.proxy.ProxyGrantingTicketStorageImpl;
import org.jasig.cas.client.proxy.ProxyRetriever;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.Test;
import org.springframework.context.support.ClassPathXmlApplicationContext;