/* * JBoss, Home of Professional Open Source. * Copyright 2008, Red Hat Middleware LLC, and individual contributors * as indicated by the @author tags. See the copyright.txt file 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.test.web.test; import java.net.HttpURLConnection; import java.util.List; import javax.management.MBeanServerConnection; import javax.management.MBeanServerInvocationHandler; import javax.management.ObjectName; import org.apache.commons.httpclient.Cookie; import org.apache.commons.httpclient.Header; import org.apache.commons.httpclient.HttpClient; import org.apache.commons.httpclient.HttpState; import org.apache.commons.httpclient.methods.PostMethod; import org.apache.commons.httpclient.methods.GetMethod; import org.jboss.test.JBossTestCase; import org.jboss.test.JBossTestSetup; import org.jboss.security.plugins.JaasSecurityManagerServiceMBean; import junit.framework.Test; import junit.framework.TestSuite; /** Tests of form authentication * * @author Scott.Stark@jboss.org * @version $Revision: 81036 $ */ public class FormAuthUnitTestCase extends JBossTestCase { private String baseURLNoAuth ; private HttpClient httpConn = new HttpClient(); public FormAuthUnitTestCase(String name) { super(name); } protected void setUp() throws Exception { super.setUp(); baseURLNoAuth = "http://" + getServerHost() + ":" + Integer.getInteger("web.port", 8080) + "/"; } /** Test form authentication of a secured servlet * * @throws Exception */ public void testFormAuth() throws Exception { log.info("+++ testFormAuth"); doSecureGetWithLogin("form-auth/restricted/SecuredServlet"); /* Access the resource without attempting a login to validate that the session is valid and that any caching on the server is working as expected. */ doSecureGet("form-auth/restricted/SecuredServlet"); } /** * Test that a bad login is redirected to the errors.jsp and that the * session j_exception is not null. * * @throws Exception */ public void testFormAuthException() throws Exception { log.info("+++ testFormAuthException"); GetMethod indexGet = new GetMethod(baseURLNoAuth+"form-auth/restricted/SecuredServlet"); int responseCode = httpConn.executeMethod(indexGet); String body = indexGet.getResponseBodyAsString(); assertTrue("Get OK("+responseCode+")", responseCode == HttpURLConnection.HTTP_OK); assertTrue("Redirected to login page", body.indexOf("j_security_check") > 0 ); HttpState state = httpConn.getState(); Cookie[] cookies = state.getCookies(); String sessionID = null; for(int c = 0; c < cookies.length; c ++) { Cookie k = cookies[c]; if( k.getName().equalsIgnoreCase("JSESSIONID") ) sessionID = k.getValue(); } getLog().debug("Saw JSESSIONID="+sessionID); // Submit the login form PostMethod formPost = new PostMethod(baseURLNoAuth+"form-auth/j_security_check"); formPost.addRequestHeader("Referer", baseURLNoAuth+"form-auth/restricted/login.html"); formPost.addParameter("j_username", "baduser"); formPost.addParameter("j_password", "badpass"); responseCode = httpConn.executeMethod(formPost.getHostConfiguration(), formPost, state); String response = formPost.getStatusText(); log.debug("responseCode="+responseCode+", response="+response); Header jex = formPost.getResponseHeader("X-JException"); log.debug("Saw X-JException, "+jex); assertNotNull("X-JException != null", jex); } /** Test form authentication of a secured servlet and validate that there is * a SecurityAssociation setting Subject. * * @throws Exception */ public void testFormAuthSubject() throws Exception { log.info("+++ testFormAuthSubject"); // Start by accessing the secured index.html of war1 HttpClient httpConn = new HttpClient(); GetMethod indexGet = new GetMethod(baseURLNoAuth+"form-auth/restricted/SecuredServlet"); indexGet.setQueryString("validateSubject=true"); int responseCode = httpConn.executeMethod(indexGet); String body = indexGet.getResponseBodyAsString(); assertTrue("Get OK", responseCode == HttpURLConnection.HTTP_OK); assertTrue("Redirected to login page", body.indexOf("j_security_check") > 0 ); HttpState state = httpConn.getState(); Cookie[] cookies = state.getCookies(); String sessionID = null; for(int c = 0; c < cookies.length; c ++) { Cookie k = cookies[c]; if( k.getName().equalsIgnoreCase("JSESSIONID") ) sessionID = k.getValue(); } getLog().debug("Saw JSESSIONID="+sessionID); // Submit the login form PostMethod formPost = new PostMethod(baseURLNoAuth+"form-auth/j_security_check"); formPost.addRequestHeader("Referer", baseURLNoAuth+"form-auth/restricted/login.html"); formPost.addParameter("j_username", "jduke"); formPost.addParameter("j_password", "theduke"); responseCode = httpConn.executeMethod(formPost.getHostConfiguration(), formPost, state); String response = formPost.getStatusText(); log.debug("responseCode="+responseCode+", response="+response); assertTrue("Saw HTTP_MOVED_TEMP", responseCode == HttpURLConnection.HTTP_MOVED_TEMP); // Follow the redirect to the SecureServlet Header location = formPost.getResponseHeader("Location"); String indexURI = location.getValue(); GetMethod war1Index = new GetMethod(indexURI); responseCode = httpConn.executeMethod(war1Index.getHostConfiguration(), war1Index, state); response = war1Index.getStatusText(); log.debug("responseCode="+responseCode+", response="+response); assertTrue("Get OK", responseCode == HttpURLConnection.HTTP_OK); body = war1Index.getResponseBodyAsString(); if( body.indexOf("j_security_check") > 0 ) fail("get of "+indexURI+" redirected to login page"); } /** Test that a post from an unsecured form to a secured servlet does not * loose its data during the redirct to the form login. * * @throws Exception */ public void testPostDataFormAuth() throws Exception { log.info("+++ testPostDataFormAuth"); // Start by accessing the secured index.html of war1 HttpClient httpConn = new HttpClient(); GetMethod indexGet = new GetMethod(baseURLNoAuth+"form-auth/unsecure_form.html"); int responseCode = httpConn.executeMethod(indexGet); assertTrue("Get OK", responseCode == HttpURLConnection.HTTP_OK); // Submit the form to /restricted/SecuredPostServlet PostMethod servletPost = new PostMethod(baseURLNoAuth+"form-auth/restricted/SecuredPostServlet"); servletPost.addParameter("checkParam", "123456"); responseCode = httpConn.executeMethod(servletPost); String body = servletPost.getResponseBodyAsString(); assertTrue("Get OK", responseCode == HttpURLConnection.HTTP_OK); assertTrue("Redirected to login page", body.indexOf("j_security_check") > 0 ); HttpState state = httpConn.getState(); Cookie[] cookies = state.getCookies(); String sessionID = null; for(int c = 0; c < cookies.length; c ++) { Cookie k = cookies[c]; if( k.getName().equalsIgnoreCase("JSESSIONID") ) sessionID = k.getValue(); } getLog().debug("Saw JSESSIONID="+sessionID); // Submit the login form PostMethod formPost = new PostMethod(baseURLNoAuth+"form-auth/j_security_check"); formPost.addRequestHeader("Referer", baseURLNoAuth+"form-auth/unsecure_form.html"); formPost.addParameter("j_username", "jduke"); formPost.addParameter("j_password", "theduke"); responseCode = httpConn.executeMethod(formPost.getHostConfiguration(), formPost, state); String response = formPost.getStatusText(); getLog().debug("responseCode="+responseCode+", response="+response); assertTrue("Saw HTTP_MOVED_TEMP", responseCode == HttpURLConnection.HTTP_MOVED_TEMP); // Follow the redirect to the SecureServlet Header location = formPost.getResponseHeader("Location"); String indexURI = location.getValue(); GetMethod war1Index = new GetMethod(indexURI); responseCode = httpConn.executeMethod(war1Index.getHostConfiguration(), war1Index, state); assertTrue("Get OK", responseCode == HttpURLConnection.HTTP_OK); body = war1Index.getResponseBodyAsString(); if( body.indexOf("j_security_check") > 0 ) fail("get of "+indexURI+" redirected to login page"); } /** Test that the war which uses <security-domain flushOnSessionInvalidation="true"> * in the jboss-web.xml does not have any jaas security domain cache entries * after the web session has been invalidated. */ public void testFlushOnSessionInvalidation() throws Exception { log.info("+++ testFlushOnSessionInvalidation"); MBeanServerConnection conn = (MBeanServerConnection) getServer(); ObjectName name = new ObjectName("jboss.security:service=JaasSecurityManager"); JaasSecurityManagerServiceMBean secMgrService = (JaasSecurityManagerServiceMBean) MBeanServerInvocationHandler.newProxyInstance(conn, name, JaasSecurityManagerServiceMBean.class, false); // Access a secured servlet to create a session and jaas cache entry doSecureGetWithLogin("form-auth/restricted/SecuredServlet"); // Validate that the jaas cache has 1 principal List principals = secMgrService.getAuthenticationCachePrincipals("jbossweb-form-auth"); assertTrue("jbossweb-form-auth has one principal", principals.size() == 1); // Logout to clear the cache doSecureGet("form-auth/Logout"); principals = secMgrService.getAuthenticationCachePrincipals("jbossweb-form-auth"); log.info("jbossweb-form-auth principals = "+principals); assertTrue("jbossweb-form-auth has no cache principals", principals.size() == 0); } public PostMethod doSecureGetWithLogin(String path) throws Exception { return doSecureGetWithLogin(path, "jduke", "theduke"); } public PostMethod doSecureGetWithLogin(String path, String username, String password) throws Exception { GetMethod indexGet = new GetMethod(baseURLNoAuth+path); int responseCode = httpConn.executeMethod(indexGet); String body = indexGet.getResponseBodyAsString(); assertTrue("Get OK("+responseCode+")", responseCode == HttpURLConnection.HTTP_OK); assertTrue("Redirected to login page", body.indexOf("j_security_check") > 0 ); HttpState state = httpConn.getState(); Cookie[] cookies = state.getCookies(); String sessionID = null; for(int c = 0; c < cookies.length; c ++) { Cookie k = cookies[c]; if( k.getName().equalsIgnoreCase("JSESSIONID") ) sessionID = k.getValue(); } getLog().debug("Saw JSESSIONID="+sessionID); // Submit the login form PostMethod formPost = new PostMethod(baseURLNoAuth+"form-auth/j_security_check"); formPost.addRequestHeader("Referer", baseURLNoAuth+"form-auth/restricted/login.html"); formPost.addParameter("j_username", username); formPost.addParameter("j_password", password); responseCode = httpConn.executeMethod(formPost.getHostConfiguration(), formPost, state); String response = formPost.getStatusText(); log.debug("responseCode="+responseCode+", response="+response); assertTrue("Saw HTTP_MOVED_TEMP", responseCode == HttpURLConnection.HTTP_MOVED_TEMP); // Follow the redirect to the SecureServlet Header location = formPost.getResponseHeader("Location"); String indexURI = location.getValue(); GetMethod war1Index = new GetMethod(indexURI); responseCode = httpConn.executeMethod(war1Index.getHostConfiguration(), war1Index, state); response = war1Index.getStatusText(); log.debug("responseCode="+responseCode+", response="+response); assertTrue("Get OK", responseCode == HttpURLConnection.HTTP_OK); body = war1Index.getResponseBodyAsString(); if( body.indexOf("j_security_check") > 0 ) fail("get of "+indexURI+" redirected to login page"); return formPost; } public void doSecureGet(String path) throws Exception { HttpState state = httpConn.getState(); Cookie[] cookies = state.getCookies(); String sessionID = null; for(int c = 0; c < cookies.length; c ++) { Cookie k = cookies[c]; if( k.getName().equalsIgnoreCase("JSESSIONID") ) sessionID = k.getValue(); } getLog().debug("Saw JSESSIONID="+sessionID); // Submit the login form GetMethod indexGet = new GetMethod(baseURLNoAuth+path); int responseCode = httpConn.executeMethod(indexGet.getHostConfiguration(), indexGet, state); assertTrue("Get OK("+responseCode+")", responseCode == HttpURLConnection.HTTP_OK); } /** One time setup for all SingleSignOnUnitTestCase unit tests */ public static Test suite() throws Exception { TestSuite suite = new TestSuite(); suite.addTest(new TestSuite(FormAuthUnitTestCase.class)); // Create an initializer for the test suite Test wrapper = new JBossTestSetup(suite) { protected void setUp() throws Exception { super.setUp(); deploy("form-auth.ear"); // Make sure the security cache is clear flushAuthCache(); //Make sure the ExtendedFormAuthenticator is registered in tomcat //Note Tomcat always binds to localhost String oname = "jboss.web:host=localhost,name=ExtendedFormAuthenticator,path=/form-auth,type=Valve"; ObjectName formAuth = new ObjectName(oname); //We have a form-auth war with FORM authenticator and that is not overriden at the webapp level // assertNotNull("Authenticator for FORM on host=localhost exists?", getServer().getObjectInstance(formAuth)); } protected void tearDown() throws Exception { undeploy("form-auth.ear"); super.tearDown(); } }; return wrapper; } }