View Javadoc

1   /*
2    * $Id: HttpSecurityFilterFunctionalTestCase.java 22518 2011-07-22 07:00:22Z claude.mamo $
3    * --------------------------------------------------------------------------------------
4    * Copyright (c) MuleSoft, Inc.  All rights reserved.  http://www.mulesoft.com
5    *
6    * The software in this package is published under the terms of the CPAL v1.0
7    * license, a copy of which has been included with this distribution in the
8    * LICENSE.txt file.
9    */
10  
11  package org.mule.module.cxf;
12  
13  import static org.junit.Assert.assertEquals;
14  import static org.junit.Assert.assertNotNull;
15  
16  import org.mule.tck.AbstractServiceAndFlowTestCase;
17  import org.mule.tck.junit4.rule.DynamicPort;
18  import org.mule.transport.http.HttpConstants;
19  
20  import java.util.Arrays;
21  import java.util.Collection;
22  
23  import org.apache.commons.httpclient.HttpClient;
24  import org.apache.commons.httpclient.UsernamePasswordCredentials;
25  import org.apache.commons.httpclient.auth.AuthScope;
26  import org.apache.commons.httpclient.methods.GetMethod;
27  import org.apache.commons.httpclient.methods.PostMethod;
28  import org.apache.commons.httpclient.methods.StringRequestEntity;
29  import org.junit.Ignore;
30  import org.junit.Rule;
31  import org.junit.Test;
32  import org.junit.runners.Parameterized.Parameters;
33  
34  public class HttpSecurityFilterFunctionalTestCase extends AbstractServiceAndFlowTestCase
35  {
36      private static String soapRequest = 
37          "<soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:unk=\"http://unknown.namespace/\">" +
38             "<soapenv:Header/>" +
39             "<soapenv:Body>" +
40                "<unk:echo>" +         
41                   "<arg0>asdf</arg0>" +
42                "</unk:echo>" +
43             "</soapenv:Body>" +
44          "</soapenv:Envelope>";
45  
46      @Rule
47      public DynamicPort dynamicPort1 = new DynamicPort("port1");
48  
49      @Rule
50      public DynamicPort dynamicPort2 = new DynamicPort("port2");
51      
52      public HttpSecurityFilterFunctionalTestCase(ConfigVariant variant, String configResources)
53      {
54          super(variant, configResources);
55      }
56  
57      @Parameters
58      public static Collection<Object[]> parameters()
59      {
60          return Arrays.asList(new Object[][]{
61              {ConfigVariant.SERVICE, "http-security-filter-test-service.xml"},
62              {ConfigVariant.FLOW, "http-security-filter-test-flow.xml"}
63          });
64      }      
65   
66      
67      /**
68       * By putting this test method that uses https first we can test MULE-4558
69       * 
70       * @throws Exception
71       */
72      @Test
73      public void testAuthenticationFailureBadCredentialsGetHttps() throws Exception
74      {
75          doGet(null, "localhost", "anonX", "anonX", "https://localhost:" + dynamicPort2.getNumber() + "/services/Echo", true, 401);
76      }
77  
78      @Test
79      public void testAuthenticationFailureNoContextGet() throws Exception
80      {
81          HttpClient client = new HttpClient();
82          client.getParams().setAuthenticationPreemptive(true);
83          GetMethod get = new GetMethod("http://localhost:" + dynamicPort1.getNumber() + "/services/Echo");
84  
85          get.setDoAuthentication(false);
86  
87          try
88          {
89              int status = client.executeMethod(get);
90              assertEquals(HttpConstants.SC_UNAUTHORIZED, status);
91              assertEquals(
92                  "Registered authentication is set to org.mule.module.spring.security.filters.http.HttpBasicAuthenticationFilter "
93                                  + "but there was no security context on the session. Authentication denied on "
94                                  + "endpoint http://localhost:" + dynamicPort1.getNumber() + "/services/Echo. Message payload is of type: "
95                                  + "String", get.getResponseBodyAsString());
96          }
97          finally
98          {
99              get.releaseConnection();
100         }
101     }
102 
103     @Test
104     public void testAuthenticationFailureNoContextPost() throws Exception
105     {
106         HttpClient client = new HttpClient();
107         client.getParams().setAuthenticationPreemptive(true);
108         PostMethod post = new PostMethod("http://localhost:" + dynamicPort1.getNumber() + "/services/Echo");
109 
110         post.setDoAuthentication(false);
111 
112         StringRequestEntity requestEntity = new StringRequestEntity(soapRequest, "text/xml", "UTF-8");
113         post.setRequestEntity(requestEntity);
114 
115         try
116         {
117             int status = client.executeMethod(post);
118             assertEquals(HttpConstants.SC_UNAUTHORIZED, status);
119             assertEquals(
120                 "Registered authentication is set to org.mule.module.spring.security.filters.http.HttpBasicAuthenticationFilter "
121                                 + "but there was no security context on the session. Authentication denied on "
122                                 + "endpoint http://localhost:" + dynamicPort1.getNumber() + "/services/Echo. Message payload is of type: "
123                                 + "ContentLengthInputStream",   post.getResponseBodyAsString());
124         }
125         finally
126         {
127             post.releaseConnection();
128         }
129     }
130 
131     @Test
132     public void testAuthenticationFailureBadCredentialsGet() throws Exception
133     {
134         doGet(null, "localhost", "anonX", "anonX", "http://localhost:" + dynamicPort1.getNumber() + "/services/Echo/echo/echo/hello", true, 401);
135     }
136 
137     @Test
138     public void testAuthenticationFailureBadCredentialsPost() throws Exception
139     {
140         doPost(null, "localhost", "anonX", "anonX", "http://localhost:" + dynamicPort1.getNumber() + "/services/Echo", true, 401);
141     }
142 
143     @Test
144     public void testAuthenticationFailureBadCredentialsPostHttps() throws Exception
145     {
146         doPost(null, "localhost", "anonX", "anonX", "https://localhost:" + dynamicPort2.getNumber() + "/services/Echo", true, 401);
147     }
148 
149     @Test
150     public void testAuthenticationAuthorisedGet() throws Exception
151     {
152         doGet(null, "localhost", "anon", "anon", "http://localhost:" + dynamicPort1.getNumber() + "/services/Echo/echo/echo/hello", false, 200);
153     }
154 
155     @Test
156     public void testAuthenticationAuthorisedGetHttps() throws Exception
157     {
158         doGet(null, "localhost", "anon", "anon", "https://localhost:" + dynamicPort2.getNumber() + "/services/Echo/echo/echo/hello", false, 200);
159     }
160 
161     @Test
162     public void testAuthenticationAuthorisedPost() throws Exception
163     {
164         doPost(null, "localhost", "anon", "anon", "http://localhost:" + dynamicPort1.getNumber() + "/services/Echo", false, 200);
165     }
166 
167     @Test
168     public void testAuthenticationAuthorisedPostHttps() throws Exception
169     {
170         doPost(null, "localhost", "anon", "anon", "https://localhost:" + dynamicPort2.getNumber() + "/services/Echo", false, 200);
171     }
172 
173     @Test
174     public void testAuthenticationAuthorisedWithHandshakeGet() throws Exception
175     {
176         doGet(null, "localhost", "anon", "anon", "http://localhost:" + dynamicPort1.getNumber() + "/services/Echo/echo/echo/hello", true, 200);
177     }
178 
179     @Test
180     public void testAuthenticationAuthorisedWithHandshakePost() throws Exception
181     {
182         doPost(null, "localhost", "anon", "anon", "http://localhost:" + dynamicPort1.getNumber() + "/services/Echo", true, 200);
183     }
184 
185     // TODO Realm validation seems to be completely ignored
186     @Ignore
187     @Test
188     public void testAuthenticationAuthorisedWithHandshakeAndBadRealmGet() throws Exception
189     {
190         doGet("blah", "localhost", "anon", "anon", "http://localhost:" + dynamicPort1.getNumber() + "/services/Echo/echo/echo/hello", true, 401);
191     }
192 
193     // TODO Realm validation seems to be completely ignored
194     @Ignore
195     @Test
196     public void testAuthenticationAuthorisedWithHandshakeAndBadRealmPost() throws Exception
197     {
198         doPost("blah", "localhost", "anon", "anon", "http://localhost:" + dynamicPort1.getNumber() + "/services/Echo", true, 401);
199     }
200 
201     @Test
202     public void testAuthenticationAuthorisedWithHandshakeAndRealmGet() throws Exception
203     {
204         doGet("mule-realm", "localhost", "ross", "ross", "http://localhost:" + dynamicPort1.getNumber() + "/services/Echo/echo/echo/hello", true, 200);
205     }
206 
207     @Test
208     public void testAuthenticationAuthorisedWithHandshakeAndRealmPost() throws Exception
209     {
210         doPost("mule-realm", "localhost", "ross", "ross", "http://localhost:" + dynamicPort1.getNumber() + "/services/Echo", true, 200);
211     }
212 
213     private void doGet(String realm,
214                        String host,
215                        String user,
216                        String pass,
217                        String url,
218                        boolean handshake,
219                        int result) throws Exception
220     {
221         HttpClient client = new HttpClient();
222         client.getParams().setAuthenticationPreemptive(true);
223         client.getState().setCredentials(new AuthScope(host, -1, realm),
224             new UsernamePasswordCredentials(user, pass));
225         GetMethod get = new GetMethod(url);
226         get.setDoAuthentication(handshake);
227 
228         try
229         {
230             int status = client.executeMethod(get);
231             if (status == HttpConstants.SC_UNAUTHORIZED && handshake == true)
232             {
233                 // doAuthentication = true means that if the request returns 401, 
234                 // the HttpClient will resend the request with credentials
235                 status = client.executeMethod(get);
236             }
237             assertEquals(result, status);
238         }
239         finally
240         {
241             get.releaseConnection();
242         }
243     }
244 
245     private void doPost(String realm,
246                         String host,
247                         String user,
248                         String pass,
249                         String url,
250                         boolean handshake,
251                         int result) throws Exception
252     {
253         HttpClient client = new HttpClient();
254         client.getParams().setAuthenticationPreemptive(true);
255         client.getState().setCredentials(new AuthScope(host, -1, realm),
256             new UsernamePasswordCredentials(user, pass));
257         PostMethod post = new PostMethod(url);
258         post.setDoAuthentication(handshake);
259         StringRequestEntity requestEntity = new StringRequestEntity(soapRequest, "text/xml", "UTF-8");
260         post.setRequestEntity(requestEntity);
261         try
262         {
263             int status = client.executeMethod(post);
264             if (status == HttpConstants.SC_UNAUTHORIZED && handshake == true)
265             {
266                 // doAuthentication = true means that if the request returns 401, 
267                 // the HttpClient will resend the request with credentials
268                 status = client.executeMethod(post);
269             }
270             assertEquals(result, status);
271             assertNotNull(post.getResponseBodyAsString());
272         }
273         finally
274         {
275             post.releaseConnection();
276         }
277     }
278 }