Author: sohil.shah(a)jboss.com
Date: 2007-07-17 12:54:01 -0400 (Tue, 17 Jul 2007)
New Revision: 7805
Added:
branches/2_6_CAS_Integration/identity/src/main/org/jboss/portal/test/identity/sso/
branches/2_6_CAS_Integration/identity/src/main/org/jboss/portal/test/identity/sso/CASTestCase.java
branches/2_6_CAS_Integration/identity/src/main/org/jboss/portal/test/identity/sso/EasySSLProtocolSocketFactory.java
branches/2_6_CAS_Integration/identity/src/main/org/jboss/portal/test/identity/sso/EasyX509TrustManager.java
branches/2_6_CAS_Integration/identity/src/resources/portal-identity-test-jar/org/jboss/portal/test/identity/sso-beans.xml
Modified:
branches/2_6_CAS_Integration/identity/build.xml
branches/2_6_CAS_Integration/identity/src/main/org/jboss/portal/identity/auth/CASAuthenticationValve.java
Log:
SSO Testing for CAS integration added
Modified: branches/2_6_CAS_Integration/identity/build.xml
===================================================================
--- branches/2_6_CAS_Integration/identity/build.xml 2007-07-17 16:30:45 UTC (rev 7804)
+++ branches/2_6_CAS_Integration/identity/build.xml 2007-07-17 16:54:01 UTC (rev 7805)
@@ -114,6 +114,7 @@
<!-- cas integration -->
<path refid="sun.servlet.classpath"/>
<path refid="yale.cas.classpath"/>
+ <path refid="apache.httpclient.classpath"/>
</path>
<path id="javac.classpath">
@@ -542,4 +543,34 @@
</x-classpath>
</execute-tests>
</target>
+
+ <target name="tests-sso" depends="init,package-tests">
+ <execute-tests>
+ <!--
+ <x-sysproperty>
+ <jvmarg value="-Xdebug"/>
+ <jvmarg
value="-Xrunjdwp:transport=dt_socket,address=8787,server=y,suspend=y"/>
+ </x-sysproperty>
+ -->
+
+ <x-test>
+ <test todir="${test.reports}"
name="org.jboss.portal.test.identity.sso.CASTestCase"/>
+ </x-test>
+
+ <x-classpath>
+ <pathelement
location="${build.lib}/portal-identity-lib.jar"/>
+ <pathelement
location="${build.lib}/portal-identity-test-lib.jar"/>
+ <path refid="jboss.portal-test.classpath"/>
+ <path refid="jboss.microcontainer.classpath"/>
+ <path refid="jboss.jbossxb.classpath"/>
+ <path refid="jbossas/core.libs.classpath"/>
+ <path refid="apache.commons.classpath"/>
+ <path refid="apache.xerces.classpath"/>
+ <path refid="apache.log4j.classpath"/>
+ <path refid="apache.codec.classpath"/>
+ <path refid="oswego.concurrent.classpath"/>
+ <path refid="junit.junit.classpath"/>
+ </x-classpath>
+ </execute-tests>
+ </target>
</project>
Modified:
branches/2_6_CAS_Integration/identity/src/main/org/jboss/portal/identity/auth/CASAuthenticationValve.java
===================================================================
---
branches/2_6_CAS_Integration/identity/src/main/org/jboss/portal/identity/auth/CASAuthenticationValve.java 2007-07-17
16:30:45 UTC (rev 7804)
+++
branches/2_6_CAS_Integration/identity/src/main/org/jboss/portal/identity/auth/CASAuthenticationValve.java 2007-07-17
16:54:01 UTC (rev 7805)
@@ -167,54 +167,96 @@
*/
private List authorizedProxies = new ArrayList();
+ /**
+ *
+ */
private String authType = null;
+ /**
+ *
+ * @return
+ */
public String getCasLogin()
{
return casLogin;
}
+ /**
+ *
+ * @param casLogin
+ */
public void setCasLogin(String casLogin)
{
this.casLogin = casLogin;
}
+ /**
+ *
+ * @return
+ */
public String getCasServerName()
{
return casServerName;
}
+ /**
+ *
+ * @param casServerName
+ */
public void setCasServerName(String casServerName)
{
this.casServerName = casServerName;
}
+ /**
+ *
+ * @return
+ */
public String getCasValidate()
{
return casValidate;
}
+ /**
+ *
+ * @param casValidate
+ */
public void setCasValidate(String casValidate)
{
this.casValidate = casValidate;
}
+ /**
+ *
+ * @return
+ */
public String getAuthType()
{
return authType;
}
+ /**
+ *
+ * @param authType
+ */
public void setAuthType(String authType)
{
this.authType = authType;
}
-
+ /**
+ *
+ * @return
+ */
public String getCasServiceUrl()
{
return this.casServiceUrl;
}
+ /**
+ *
+ * @param casServiceUrl
+ */
public void setCasServiceUrl(String casServiceUrl)
{
this.casServiceUrl = casServiceUrl;
@@ -227,9 +269,7 @@
ServletException
{
HttpServletRequest httpRequest = (HttpServletRequest) request;
- HttpSession session = httpRequest.getSession();
- this.casRenew = true; // this value helps with logout...otherwise user
- // is never able to logout
+ HttpSession session = httpRequest.getSession();
String requestURI = request.getRequestURI();
if ((requestURI.indexOf("/auth/") != -1
@@ -244,7 +284,7 @@
return;
}
- // perform CAS logout if needed
+
if (request.getParameter("ticket") != null
&& session.getAttribute(CAS_FILTER_USER) == null)
{
@@ -391,7 +431,22 @@
return CASReceipt.getReceipt(pv);
}
+
/**
+ * Redirects the user to CAS, determining the service from the request.
+ */
+ private void redirectToCAS(HttpServletRequest request,
+ HttpServletResponse response) throws IOException, ServletException
+ {
+ String casLoginString = casLogin + "?service="
+ + getService((HttpServletRequest) request)
+ + ((casRenew) ? "&renew=true" : "")
+ + (casGateway ? "&gateway=true" : "");
+
+ ((HttpServletResponse) response).sendRedirect(casLoginString);
+ }
+
+ /**
* Returns either the configured service or figures it out for the current
* request. The returned service is URL-encoded.
*/
@@ -419,18 +474,4 @@
return serviceString;
}
-
- /**
- * Redirects the user to CAS, determining the service from the request.
- */
- private void redirectToCAS(HttpServletRequest request,
- HttpServletResponse response) throws IOException, ServletException
- {
- String casLoginString = casLogin + "?service="
- + getService((HttpServletRequest) request)
- + ((casRenew) ? "&renew=true" : "")
- + (casGateway ? "&gateway=true" : "");
-
- ((HttpServletResponse) response).sendRedirect(casLoginString);
- }
}
Added:
branches/2_6_CAS_Integration/identity/src/main/org/jboss/portal/test/identity/sso/CASTestCase.java
===================================================================
---
branches/2_6_CAS_Integration/identity/src/main/org/jboss/portal/test/identity/sso/CASTestCase.java
(rev 0)
+++
branches/2_6_CAS_Integration/identity/src/main/org/jboss/portal/test/identity/sso/CASTestCase.java 2007-07-17
16:54:01 UTC (rev 7805)
@@ -0,0 +1,605 @@
+/******************************************************************************
+ * JBoss, a division of Red Hat *
+ * Copyright 2006, Red Hat Middleware, LLC, and individual *
+ * contributors as indicated by the @authors tag. See the *
+ * copyright.txt in the distribution for a full listing of *
+ * individual contributors. *
+ * *
+ * This is free software; you can redistribute it and/or modify it *
+ * under the terms of the GNU Lesser General Public License as *
+ * published by the Free Software Foundation; either version 2.1 of *
+ * the License, or (at your option) any later version. *
+ * *
+ * This software is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
+ * Lesser General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU Lesser General Public *
+ * License along with this software; if not, write to the Free *
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA *
+ * 02110-1301 USA, or see the FSF site:
http://www.fsf.org. *
+ ******************************************************************************/
+package org.jboss.portal.test.identity.sso;
+
+import java.util.Map;
+import java.util.Set;
+import java.util.Iterator;
+import java.util.HashMap;
+
+import org.jboss.portal.test.framework.TestRuntimeContext;
+
+import org.apache.commons.httpclient.HttpClient;
+import org.apache.commons.httpclient.Cookie;
+import org.apache.commons.httpclient.NameValuePair;
+import org.apache.commons.httpclient.methods.GetMethod;
+import org.apache.commons.httpclient.methods.PostMethod;
+import org.apache.commons.httpclient.protocol.Protocol;
+
+import junit.framework.TestCase;
+
+/**
+ * @author <a href="mailto:sshah@redhat.com">Sohil Shah</a>
+ *
+ */
+public class CASTestCase extends TestCase
+{
+ /**
+ *
+ */
+ private String portalServer = null;
+ private String firstPortalContext = null;
+ private String secondPortalContext = null;
+ private String userLoggedInIndicator = null;
+ private String username = null;
+ private String password = null;
+
+ /**
+ *
+ */
+ protected TestRuntimeContext runtimeContext = null;
+
+ /**
+ *
+ */
+ protected void setUp() throws Exception
+ {
+ super.setUp();
+
+ this.runtimeContext = new
TestRuntimeContext("org/jboss/portal/test/identity/sso-beans.xml");
+
+ this.runtimeContext.addBean("CASConfig", this);
+
+ this.runtimeContext.start();
+
+ //SSL setup
+ Protocol.registerProtocol("https",new Protocol("https", new
EasySSLProtocolSocketFactory(), 443));
+ }
+
+ /**
+ *
+ */
+ protected void tearDown() throws Exception
+ {
+ super.tearDown();
+
+ //Service stoppage
+ this.runtimeContext.stop();
+
+ //Data cleanup
+ this.runtimeContext = null;
+ this.portalServer = null;
+ this.firstPortalContext = null;
+ this.secondPortalContext = null;
+ }
+
+ /**
+ *
+ * @return
+ */
+ public String getFirstPortalContext()
+ {
+ return firstPortalContext;
+ }
+
+ /**
+ *
+ * @param firstPortalContext
+ */
+ public void setFirstPortalContext(String firstPortalContext)
+ {
+ this.firstPortalContext = firstPortalContext;
+ }
+
+ /**
+ *
+ * @return
+ */
+ public String getPortalServer()
+ {
+ return portalServer;
+ }
+
+ /**
+ *
+ * @param portalServer
+ */
+ public void setPortalServer(String portalServer)
+ {
+ this.portalServer = portalServer;
+ }
+
+ /**
+ *
+ * @return
+ */
+ public String getSecondPortalContext()
+ {
+ return secondPortalContext;
+ }
+
+ /**
+ *
+ * @param secondPortalContext
+ */
+ public void setSecondPortalContext(String secondPortalContext)
+ {
+ this.secondPortalContext = secondPortalContext;
+ }
+
+ /**
+ *
+ * @return
+ */
+ public String getUserLoggedInIndicator()
+ {
+ return userLoggedInIndicator;
+ }
+
+ /**
+ *
+ * @param userLoggedInIndicator
+ */
+ public void setUserLoggedInIndicator(String userLoggedInIndicator)
+ {
+ this.userLoggedInIndicator = userLoggedInIndicator;
+ }
+
+ /**
+ *
+ * @return
+ */
+ public String getPassword()
+ {
+ return password;
+ }
+
+ /**
+ *
+ * @param password
+ */
+ public void setPassword(String password)
+ {
+ this.password = password;
+ }
+
+ /**
+ *
+ * @return
+ */
+ public String getUsername()
+ {
+ return username;
+ }
+
+ /**
+ *
+ * @param username
+ */
+ public void setUsername(String username)
+ {
+ this.username = username;
+ }
+
+ /**
+ *
+ * @throws Exception
+ */
+ public void test() throws Exception
+ {
+ Cookie casCookie = null;
+ String firstPortalFinalResponse = null;
+ String secondPortalFinalResponse = null;
+
+ //Load the main portal page on firstPortalContext
+ String firstContextPortalUrl =
"http://"+this.portalServer+"/"+this.firstPortalContext;
+ WebConversation portalConversation = this.startConversation(firstContextPortalUrl);
+ TestCase.assertFalse(this.isUserLoggedIn(portalConversation.getResponse()));
+
+ //Click the Login link on the firstPortalContext
+ String firstContextLoginUrl = firstContextPortalUrl +
"/auth/portal/default/default";
+ this.sendGet(firstContextLoginUrl, portalConversation);
+
+ //Perform redirect to the CAS Server
+ TestCase.assertNotNull(portalConversation.getRedirectLocation());
+ TestCase.assertEquals(portalConversation.getStatusCode(), 302);
+ String casLocation = portalConversation.getRedirectLocation();
+ WebConversation casConversation = this.startConversation(casLocation);
+ String response = casConversation.getResponse();
+ //Extract the conversionId from the response
+ int searchIndex = response.indexOf("value=\"_c")+7;
+ int endIndex = response.indexOf('"', searchIndex);
+ String lt = response.substring(searchIndex,endIndex);
+
+ //Perform HTTP Post based authentication with the CAS Server
+ Map postParams = new HashMap();
+ postParams.put("username", this.username);
+ postParams.put("password", this.password);
+ postParams.put("_eventId", "submit");
+ postParams.put("lt",lt);
+ this.sendPost(casLocation,postParams, casConversation);
+
+ //The Portal Session should now be autenticated
+ TestCase.assertNotNull(casConversation.getRedirectLocation());
+ TestCase.assertEquals(casConversation.getStatusCode(), 302);
+
TestCase.assertTrue(casConversation.getRedirectLocation().indexOf(firstContextLoginUrl) !=
-1);
+ TestCase.assertNotNull(casConversation.getCasCookie());
+ String goBack = casConversation.getRedirectLocation();
+ casCookie = casConversation.getCasCookie();
+ portalConversation = this.startConversation(goBack);
+ firstPortalFinalResponse = portalConversation.getResponse();
+ TestCase.assertTrue(this.isUserLoggedIn(firstPortalFinalResponse));
+
+ //Load the main portal page on secondPortalContext
+ String secondContextPortalUrl =
"http://"+this.portalServer+"/"+this.secondPortalContext;
+ portalConversation = this.startConversation(secondContextPortalUrl);
+
+ //Click the Login Link on the secondPortalContext
+ String secondContextLoginUrl = secondContextPortalUrl +
"/auth/portal/default/default";
+ this.sendGet(secondContextLoginUrl, portalConversation);
+
+ //Perform re-direct to the CAS Server but this time sending in the CAS cookie
+ TestCase.assertNotNull(portalConversation.getRedirectLocation());
+ TestCase.assertEquals(portalConversation.getStatusCode(), 302);
+ casLocation = portalConversation.getRedirectLocation();
+ casConversation = this.startConversation(casLocation,casCookie);
+
+
+ //Assert the redirect and it should be to the CAS Server, but this time
+ //It should end up with an Authenticated session back to the secondPortalContext
+ secondPortalFinalResponse = casConversation.getResponse();
+ TestCase.assertTrue(this.isUserLoggedIn(secondPortalFinalResponse));
+
+ //Assert and make sure its the same user logged into both Portals
+ String firstPortalUser = this.extractLoggedInUser(firstPortalFinalResponse);
+ String secondPortalUser = this.extractLoggedInUser(secondPortalFinalResponse);
+ TestCase.assertEquals(firstPortalUser, this.username);
+ TestCase.assertEquals(secondPortalUser, this.username);
+ TestCase.assertEquals(firstPortalUser, secondPortalUser);
+ }
+
+ /**
+ *
+ * @param portalUrl
+ * @return
+ * @throws Exception
+ */
+ private WebConversation startConversation(String portalUrl) throws Exception
+ {
+ WebConversation conversation = null;
+
+ HttpClient httpClient = new HttpClient();
+ GetMethod getMethod = new GetMethod(portalUrl);
+ try
+ {
+ conversation = new WebConversation();
+
+ int statusCode = httpClient.executeMethod(getMethod);
+ String response = getMethod.getResponseBodyAsString();
+
+ Cookie[] cookies = httpClient.getState().getCookies();
+ for(int i=0;i<cookies.length;i++)
+ {
+ if(cookies[i].getName().equals("JSESSIONID"))
+ {
+ conversation.setSessionId(cookies[i].getValue());
+ }
+ }
+
+ conversation.setClient(httpClient);
+ conversation.setStatusCode(statusCode);
+ conversation.setResponse(response);
+ }
+ finally
+ {
+ if(getMethod != null)
+ {
+ getMethod.releaseConnection();
+ }
+ }
+
+ return conversation;
+ }
+
+ /**
+ *
+ * @param portalUrl
+ * @return
+ * @throws Exception
+ */
+ private WebConversation startConversation(String portalUrl, Cookie casCookie) throws
Exception
+ {
+ WebConversation conversation = null;
+
+ HttpClient httpClient = new HttpClient();
+ GetMethod getMethod = new GetMethod(portalUrl);
+
+ //Set casCookie to be sent in
+
getMethod.setRequestHeader("Cookie",casCookie.getName()+"="+casCookie.getValue());
+
+ try
+ {
+ conversation = new WebConversation();
+
+ int statusCode = httpClient.executeMethod(getMethod);
+ String response = getMethod.getResponseBodyAsString();
+
+ Cookie[] cookies = httpClient.getState().getCookies();
+ for(int i=0;i<cookies.length;i++)
+ {
+ if(cookies[i].getName().equals("JSESSIONID"))
+ {
+ conversation.setSessionId(cookies[i].getValue());
+ }
+ }
+
+ conversation.setClient(httpClient);
+ conversation.setStatusCode(statusCode);
+ conversation.setResponse(response);
+ }
+ finally
+ {
+ if(getMethod != null)
+ {
+ getMethod.releaseConnection();
+ }
+ }
+
+ return conversation;
+ }
+
+ /**
+ *
+ * @param portalUrl
+ * @param conversation
+ * @throws Exception
+ */
+ private void sendGet(String portalUrl,WebConversation conversation) throws Exception
+ {
+ HttpClient httpClient = conversation.getClient();
+
+ GetMethod getMethod = new GetMethod(portalUrl);
+ getMethod.setFollowRedirects(false);
+ try
+ {
+ int statusCode = httpClient.executeMethod(getMethod);
+
+ String response = getMethod.getResponseBodyAsString();
+
+ Cookie[] cookies = httpClient.getState().getCookies();
+ for(int i=0;i<cookies.length;i++)
+ {
+ if(cookies[i].getName().equals("JSESSIONID"))
+ {
+ conversation.setSessionId(cookies[i].getValue());
+ }
+ }
+
+ conversation.setStatusCode(statusCode);
+ conversation.setResponse(response);
+
+ if(statusCode == 302)
+ {
+ //Store the redirect location
+ String location =
getMethod.getResponseHeader("Location").getValue();
+ conversation.setRedirectLocation(location);
+ }
+ }
+ finally
+ {
+ if(getMethod != null)
+ {
+ getMethod.releaseConnection();
+ }
+ }
+ }
+
+
+ /**
+ *
+ * @param url
+ * @param parameters
+ * @param conversation
+ * @throws Exception
+ */
+ private void sendPost(String url,Map parameters,WebConversation conversation) throws
Exception
+ {
+ HttpClient httpClient = conversation.getClient();
+
+ PostMethod postMethod = new PostMethod(url);
+
+ //Add post parameters
+ Set keySet = parameters.keySet();
+ NameValuePair[] postdata = new NameValuePair[keySet.size()];
+ int index = 0;
+ for(Iterator itr=keySet.iterator();itr.hasNext();)
+ {
+ String name = (String)itr.next();
+ String value = (String)parameters.get(name);
+ postdata[index++] = new NameValuePair(name,value);
+ }
+ postMethod.setRequestBody(postdata);
+ try
+ {
+ int statusCode = httpClient.executeMethod(postMethod);
+
+ String response = postMethod.getResponseBodyAsString();
+
+ Cookie[] cookies = httpClient.getState().getCookies();
+ for(int i=0;i<cookies.length;i++)
+ {
+ if(cookies[i].getName().equals("JSESSIONID"))
+ {
+ conversation.setSessionId(cookies[i].getValue());
+ }
+ if(cookies[i].getName().equals("CASTGC"))
+ {
+ conversation.setCasCookie(cookies[i]);
+ }
+ }
+
+ conversation.setStatusCode(statusCode);
+ conversation.setResponse(response);
+
+ if(statusCode == 302)
+ {
+ //Store the redirect location
+ String location =
postMethod.getResponseHeader("Location").getValue();
+ conversation.setRedirectLocation(location);
+ }
+ }
+ finally
+ {
+ if(postMethod != null)
+ {
+ postMethod.releaseConnection();
+ }
+ }
+ }
+
+ /**
+ *
+ * @param response
+ * @return
+ */
+ private boolean isUserLoggedIn(String response)
+ {
+ boolean isUserLoggedIn = false;
+
+ isUserLoggedIn = (response.indexOf(this.userLoggedInIndicator) != -1);
+
+ return isUserLoggedIn;
+ }
+
+ /**
+ *
+ * @param response
+ * @return
+ */
+ private String extractLoggedInUser(String response)
+ {
+ String loggedInUser = null;
+
+ int startIndex = response.indexOf(this.userLoggedInIndicator) +
this.userLoggedInIndicator.length();
+ int endIndex = response.indexOf("<",startIndex);
+
+ loggedInUser = response.substring(startIndex,endIndex).trim();
+
+ return loggedInUser;
+ }
+
+ /**
+ *
+ * @author <a href="mailto:sshah@redhat.com">Sohil Shah</a>
+ *
+ */
+ private static class WebConversation
+ {
+ /**
+ *
+ */
+ private HttpClient client = null;
+ private String sessionId = null;
+ private int statusCode = 0;
+ private String response = null;
+ private String redirectLocation = null;
+ private Cookie casCookie = null;
+
+ /**
+ *
+ *
+ */
+ public WebConversation()
+ {
+
+ }
+
+ /**
+ *
+ * @return
+ */
+ public HttpClient getClient()
+ {
+ return this.client;
+ }
+
+ /**
+ *
+ * @param client
+ */
+ public void setClient(HttpClient client)
+ {
+ this.client = client;
+ }
+
+ public String getResponse()
+ {
+ return response;
+ }
+
+ public void setResponse(String response)
+ {
+ this.response = response;
+ }
+
+ public int getStatusCode()
+ {
+ return statusCode;
+ }
+
+ public void setStatusCode(int statusCode)
+ {
+ this.statusCode = statusCode;
+ }
+
+ public String getSessionId()
+ {
+ return sessionId;
+ }
+
+ public void setSessionId(String sessionId)
+ {
+ this.sessionId = sessionId;
+ }
+
+ public String getRedirectLocation()
+ {
+ return redirectLocation;
+ }
+
+ public void setRedirectLocation(String redirectLocation)
+ {
+ this.redirectLocation = redirectLocation;
+ }
+
+ public Cookie getCasCookie()
+ {
+ return casCookie;
+ }
+
+ public void setCasCookie(Cookie casCookie)
+ {
+ this.casCookie = casCookie;
+ }
+ }
+}
Added:
branches/2_6_CAS_Integration/identity/src/main/org/jboss/portal/test/identity/sso/EasySSLProtocolSocketFactory.java
===================================================================
---
branches/2_6_CAS_Integration/identity/src/main/org/jboss/portal/test/identity/sso/EasySSLProtocolSocketFactory.java
(rev 0)
+++
branches/2_6_CAS_Integration/identity/src/main/org/jboss/portal/test/identity/sso/EasySSLProtocolSocketFactory.java 2007-07-17
16:54:01 UTC (rev 7805)
@@ -0,0 +1,233 @@
+/*
+ * $Header:
/home/jerenkrantz/tmp/commons/commons-convert/cvs/home/cvs/jakarta-commons//httpclient/src/contrib/org/apache/commons/httpclient/contrib/ssl/EasySSLProtocolSocketFactory.java,v
1.7 2004/06/11 19:26:27 olegk Exp $
+ * $Revision$
+ * $Date$
+ *
+ * ====================================================================
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF 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
+ *
+ *
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.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * <
http://www.apache.org/>.
+ *
+ */
+
+package org.jboss.portal.test.identity.sso;
+
+import java.io.IOException;
+import java.net.InetAddress;
+import java.net.InetSocketAddress;
+import java.net.Socket;
+import java.net.SocketAddress;
+import java.net.UnknownHostException;
+
+import org.apache.commons.httpclient.ConnectTimeoutException;
+import org.apache.commons.httpclient.HttpClientError;
+import org.apache.commons.httpclient.params.HttpConnectionParams;
+import org.apache.commons.httpclient.protocol.SecureProtocolSocketFactory;
+
+import javax.net.SocketFactory;
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.TrustManager;
+
+/**
+ * <p>
+ * EasySSLProtocolSocketFactory can be used to creats SSL {@link Socket}s that
+ * accept self-signed certificates.
+ * </p>
+ * <p>
+ * This socket factory SHOULD NOT be used for productive systems due to security
+ * reasons, unless it is a concious decision and you are perfectly aware of
+ * security implications of accepting self-signed certificates
+ * </p>
+ *
+ * <p>
+ * Example of using custom protocol socket factory for a specific host:
+ *
+ * <pre>
+ * Protocol easyhttps = new Protocol("https", new
EasySSLProtocolSocketFactory(),
+ * 443);
+ * HttpClient client = new HttpClient();
+ * client.getHostConfiguration().setHost("localhost", 443, easyhttps);
+ * // use relative url only
+ * GetMethod httpget = new GetMethod("/");
+ * client.executeMethod(httpget);
+ * </pre>
+ *
+ * </p>
+ * <p>
+ * Example of using custom protocol socket factory per default instead of the
+ * standard one:
+ *
+ * <pre>
+ * Protocol easyhttps = new Protocol("https", new
EasySSLProtocolSocketFactory(),
+ * 443);
+ * Protocol.registerProtocol("https", easyhttps);
+ * HttpClient client = new HttpClient();
+ * GetMethod httpget = new GetMethod("https://localhost/");
+ * client.executeMethod(httpget);
+ * </pre>
+ *
+ * </p>
+ *
+ * @author <a href="mailto:oleg -at- ural.ru">Oleg
Kalnichevski</a>
+ *
+ * <p>
+ * DISCLAIMER: HttpClient developers DO NOT actively support this component. The
+ * component is provided as a reference material, which may be inappropriate for
+ * use without additional customization.
+ * </p>
+ */
+
+public class EasySSLProtocolSocketFactory implements
+ SecureProtocolSocketFactory
+{
+
+ private SSLContext sslcontext = null;
+
+ /**
+ * Constructor for EasySSLProtocolSocketFactory.
+ */
+ public EasySSLProtocolSocketFactory()
+ {
+ super();
+ }
+
+ private static SSLContext createEasySSLContext()
+ {
+ try
+ {
+ SSLContext context = SSLContext.getInstance("SSL");
+ context.init(null, new TrustManager[]
+ { new EasyX509TrustManager(null) }, null);
+ return context;
+ }
+ catch (Exception e)
+ {
+ throw new HttpClientError(e.toString());
+ }
+ }
+
+ private SSLContext getSSLContext()
+ {
+ if (this.sslcontext == null)
+ {
+ this.sslcontext = createEasySSLContext();
+ }
+ return this.sslcontext;
+ }
+
+ /**
+ * @see
SecureProtocolSocketFactory#createSocket(java.lang.String,int,java.net.InetAddress,int)
+ */
+ public Socket createSocket(String host, int port, InetAddress clientHost,
+ int clientPort) throws IOException, UnknownHostException
+ {
+
+ return getSSLContext().getSocketFactory().createSocket(host, port,
+ clientHost, clientPort);
+ }
+
+ /**
+ * Attempts to get a new socket connection to the given host within the given
+ * time limit.
+ * <p>
+ * To circumvent the limitations of older JREs that do not support connect
+ * timeout a controller thread is executed. The controller thread attempts to
+ * create a new socket within the given limit of time. If socket constructor
+ * does not return until the timeout expires, the controller terminates and
+ * throws an {@link ConnectTimeoutException}
+ * </p>
+ *
+ * @param host
+ * the host name/IP
+ * @param port
+ * the port on the host
+ * @param clientHost
+ * the local host name/IP to bind the socket to
+ * @param clientPort
+ * the port on the local machine
+ * @param params
+ * {@link HttpConnectionParams Http connection parameters}
+ *
+ * @return Socket a new socket
+ *
+ * @throws IOException
+ * if an I/O error occurs while creating the socket
+ * @throws UnknownHostException
+ * if the IP address of the host cannot be determined
+ */
+ public Socket createSocket(final String host, final int port,
+ final InetAddress localAddress, final int localPort,
+ final HttpConnectionParams params) throws IOException,
+ UnknownHostException, ConnectTimeoutException
+ {
+ if (params == null)
+ {
+ throw new IllegalArgumentException("Parameters may not be null");
+ }
+ int timeout = params.getConnectionTimeout();
+ SocketFactory socketfactory = getSSLContext().getSocketFactory();
+ if (timeout == 0)
+ {
+ return socketfactory.createSocket(host, port, localAddress, localPort);
+ }
+ else
+ {
+ Socket socket = socketfactory.createSocket();
+ SocketAddress localaddr = new InetSocketAddress(localAddress,
+ localPort);
+ SocketAddress remoteaddr = new InetSocketAddress(host, port);
+ socket.bind(localaddr);
+ socket.connect(remoteaddr, timeout);
+ return socket;
+ }
+ }
+
+ /**
+ * @see SecureProtocolSocketFactory#createSocket(java.lang.String,int)
+ */
+ public Socket createSocket(String host, int port) throws IOException,
+ UnknownHostException
+ {
+ return getSSLContext().getSocketFactory().createSocket(host, port);
+ }
+
+ /**
+ * @see
SecureProtocolSocketFactory#createSocket(java.net.Socket,java.lang.String,int,boolean)
+ */
+ public Socket createSocket(Socket socket, String host, int port,
+ boolean autoClose) throws IOException, UnknownHostException
+ {
+ return getSSLContext().getSocketFactory().createSocket(socket, host,
+ port, autoClose);
+ }
+
+ public boolean equals(Object obj)
+ {
+ return ((obj != null) && obj.getClass().equals(
+ EasySSLProtocolSocketFactory.class));
+ }
+
+ public int hashCode()
+ {
+ return EasySSLProtocolSocketFactory.class.hashCode();
+ }
+
+}
Added:
branches/2_6_CAS_Integration/identity/src/main/org/jboss/portal/test/identity/sso/EasyX509TrustManager.java
===================================================================
---
branches/2_6_CAS_Integration/identity/src/main/org/jboss/portal/test/identity/sso/EasyX509TrustManager.java
(rev 0)
+++
branches/2_6_CAS_Integration/identity/src/main/org/jboss/portal/test/identity/sso/EasyX509TrustManager.java 2007-07-17
16:54:01 UTC (rev 7805)
@@ -0,0 +1,109 @@
+/*
+* ====================================================================
+*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF 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
+*
+*
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.
+* ====================================================================
+*
+* This software consists of voluntary contributions made by many
+* individuals on behalf of the Apache Software Foundation. For more
+* information on the Apache Software Foundation, please see
+* <
http://www.apache.org/>.
+*
+*/
+
+package org.jboss.portal.test.identity.sso;
+
+import java.security.KeyStore;
+import java.security.KeyStoreException;
+import java.security.NoSuchAlgorithmException;
+import java.security.cert.CertificateException;
+import java.security.cert.X509Certificate;
+
+import javax.net.ssl.TrustManagerFactory;
+import javax.net.ssl.TrustManager;
+import javax.net.ssl.X509TrustManager;
+
+/**
+* <p>
+* EasyX509TrustManager unlike default {@link X509TrustManager} accepts
+* self-signed certificates.
+* </p>
+* <p>
+* This trust manager SHOULD NOT be used for productive systems
+* due to security reasons, unless it is a concious decision and
+* you are perfectly aware of security implications of accepting
+* self-signed certificates
+* </p>
+*
+* @author <a href="mailto:adrian.sutton@ephox.com">Adrian
Sutton</a>
+* @author <a href="mailto:oleg@ural.ru">Oleg Kalnichevski</a>
+*
+* <p>
+* DISCLAIMER: HttpClient developers DO NOT actively support this component.
+* The component is provided as a reference material, which may be inappropriate
+* for use without additional customization.
+* </p>
+*/
+
+public class EasyX509TrustManager implements X509TrustManager
+{
+ private X509TrustManager standardTrustManager = null;
+
+ /**
+ * Constructor for EasyX509TrustManager.
+ */
+ public EasyX509TrustManager(KeyStore keystore) throws NoSuchAlgorithmException,
KeyStoreException {
+ super();
+ TrustManagerFactory factory =
TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
+ factory.init(keystore);
+ TrustManager[] trustmanagers = factory.getTrustManagers();
+ if (trustmanagers.length == 0) {
+ throw new NoSuchAlgorithmException("no trust manager found");
+ }
+ this.standardTrustManager = (X509TrustManager)trustmanagers[0];
+ }
+
+ /**
+ * @see javax.net.ssl.X509TrustManager#checkClientTrusted(X509Certificate[],String
authType)
+ */
+ public void checkClientTrusted(X509Certificate[] certificates,String authType) throws
CertificateException {
+ standardTrustManager.checkClientTrusted(certificates,authType);
+ }
+
+ /**
+ * @see javax.net.ssl.X509TrustManager#checkServerTrusted(X509Certificate[],String
authType)
+ */
+ public void checkServerTrusted(X509Certificate[] certificates,String authType) throws
CertificateException {
+ /*if ((certificates != null) && LOG.isDebugEnabled()) {
+ LOG.debug("Server certificate chain:");
+ for (int i = 0; i < certificates.length; i++) {
+ LOG.debug("X509Certificate[" + i + "]=" +
certificates[i]);
+ }
+ }*/
+ if ((certificates != null) && (certificates.length == 1)) {
+ certificates[0].checkValidity();
+ } else {
+ standardTrustManager.checkServerTrusted(certificates,authType);
+ }
+ }
+
+ /**
+ * @see javax.net.ssl.X509TrustManager#getAcceptedIssuers()
+ */
+ public X509Certificate[] getAcceptedIssuers() {
+ return this.standardTrustManager.getAcceptedIssuers();
+ }
+}
\ No newline at end of file
Added:
branches/2_6_CAS_Integration/identity/src/resources/portal-identity-test-jar/org/jboss/portal/test/identity/sso-beans.xml
===================================================================
---
branches/2_6_CAS_Integration/identity/src/resources/portal-identity-test-jar/org/jboss/portal/test/identity/sso-beans.xml
(rev 0)
+++
branches/2_6_CAS_Integration/identity/src/resources/portal-identity-test-jar/org/jboss/portal/test/identity/sso-beans.xml 2007-07-17
16:54:01 UTC (rev 7805)
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ ~ JBoss, a division of Red Hat ~
+ ~ Copyright 2006, Red Hat Middleware, LLC, and individual ~
+ ~ contributors as indicated by the @authors tag. See the ~
+ ~ copyright.txt in the distribution for a full listing of ~
+ ~ individual contributors. ~
+ ~ ~
+ ~ This is free software; you can redistribute it and/or modify it ~
+ ~ under the terms of the GNU Lesser General Public License as ~
+ ~ published by the Free Software Foundation; either version 2.1 of ~
+ ~ the License, or (at your option) any later version. ~
+ ~ ~
+ ~ This software is distributed in the hope that it will be useful, ~
+ ~ but WITHOUT ANY WARRANTY; without even the implied warranty of ~
+ ~ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ~
+ ~ Lesser General Public License for more details. ~
+ ~ ~
+ ~ You should have received a copy of the GNU Lesser General Public ~
+ ~ License along with this software; if not, write to the Free ~
+ ~ Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA ~
+ ~ 02110-1301 USA, or see the FSF site:
http://www.fsf.org. ~
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-->
+
+<deployment
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="urn:jboss:bean-deployer bean-deployer_1_0.xsd"
+ xmlns="urn:jboss:bean-deployer">
+ <bean name="CASConfig"
class="org.jboss.portal.test.identity.sso.CASTestCase">
+ <constructor factoryMethod="getBean">
+ <factory bean="BeanFactory"/>
+ <parameter>CASConfig</parameter>
+ </constructor>
+ <property name="portalServer">localhost</property>
+ <property name="firstPortalContext">portal</property>
+ <property name="secondPortalContext">portal2</property>
+ <property name="userLoggedInIndicator">Logged in
as:</property>
+ <property name="username">user</property>
+ <property name="password">user</property>
+ </bean>
+</deployment>