1 package org.apache.archiva.webdav;
4 * Licensed to the Apache Software Foundation (ASF) under one
5 * or more contributor license agreements. See the NOTICE file
6 * distributed with this work for additional information
7 * regarding copyright ownership. The ASF licenses this file
8 * to you under the Apache License, Version 2.0 (the
9 * "License"); you may not use this file except in compliance
10 * with the License. You may obtain a copy of the License at
12 * http://www.apache.org/licenses/LICENSE-2.0
14 * Unless required by applicable law or agreed to in writing,
15 * software distributed under the License is distributed on an
16 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17 * KIND, either express or implied. See the License for the
18 * specific language governing permissions and limitations
22 import com.meterware.httpunit.GetMethodWebRequest;
23 import com.meterware.httpunit.HttpUnitOptions;
24 import com.meterware.httpunit.PutMethodWebRequest;
25 import com.meterware.httpunit.WebRequest;
26 import com.meterware.httpunit.WebResponse;
27 import com.meterware.servletunit.InvocationContext;
28 import com.meterware.servletunit.ServletRunner;
29 import com.meterware.servletunit.ServletUnitClient;
30 import junit.framework.TestCase;
31 import net.sf.ehcache.CacheManager;
32 import org.apache.archiva.redback.authentication.AuthenticationException;
33 import org.apache.archiva.redback.users.User;
34 import org.apache.archiva.repository.audit.TestAuditListener;
35 import org.apache.archiva.security.common.ArchivaRoleConstants;
36 import org.apache.commons.io.FileUtils;
37 import org.apache.jackrabbit.webdav.DavSessionProvider;
38 import org.apache.archiva.configuration.ArchivaConfiguration;
39 import org.apache.archiva.configuration.Configuration;
40 import org.apache.archiva.configuration.ManagedRepositoryConfiguration;
41 import org.apache.archiva.security.ServletAuthenticator;
42 import org.apache.archiva.redback.authentication.AuthenticationResult;
43 import org.apache.archiva.redback.authorization.UnauthorizedException;
44 import org.apache.archiva.redback.system.DefaultSecuritySession;
45 import org.apache.archiva.redback.system.SecuritySession;
46 import org.apache.archiva.redback.users.memory.SimpleUser;
47 import org.apache.archiva.redback.integration.filter.authentication.HttpAuthenticator;
48 import org.apache.archiva.redback.integration.filter.authentication.basic.HttpBasicAuthentication;
49 import org.easymock.MockControl;
50 import org.easymock.classextension.MockClassControl;
51 import org.junit.After;
52 import org.junit.Before;
53 import org.junit.Test;
54 import org.junit.runner.RunWith;
55 import org.springframework.context.ApplicationContext;
56 import org.springframework.test.context.ContextConfiguration;
58 import javax.inject.Inject;
59 import javax.servlet.http.HttpServletResponse;
61 import java.io.IOException;
62 import java.io.InputStream;
63 import org.apache.archiva.test.utils.ArchivaSpringJUnit4ClassRunner;
66 * RepositoryServletSecurityTest Test the flow of the authentication and authorization checks. This does not necessarily
67 * perform redback security checking.
71 @RunWith( ArchivaSpringJUnit4ClassRunner.class )
72 @ContextConfiguration( locations = { "classpath*:/META-INF/spring-context.xml", "classpath*:/spring-context.xml" } )
73 public class RepositoryServletSecurityTest
76 protected static final String REPOID_INTERNAL = "internal";
78 protected ServletUnitClient sc;
80 protected File repoRootInternal;
82 private ServletRunner sr;
84 protected ArchivaConfiguration archivaConfiguration;
86 private DavSessionProvider davSessionProvider;
88 private MockControl servletAuthControl;
90 private ServletAuthenticator servletAuth;
92 private MockClassControl httpAuthControl;
94 private HttpAuthenticator httpAuth;
96 private RepositoryServlet servlet;
99 ApplicationContext applicationContext;
107 String appserverBase = System.getProperty( "appserver.base", new File( "target/appserver-base" ).getAbsolutePath() );
109 File testConf = new File( "src/test/resources/repository-archiva.xml" );
110 File testConfDest = new File( appserverBase, "conf/archiva.xml" );
111 FileUtils.copyFile( testConf, testConfDest );
113 repoRootInternal = new File( appserverBase, "data/repositories/internal" );
115 archivaConfiguration = applicationContext.getBean( ArchivaConfiguration.class );
116 Configuration config = archivaConfiguration.getConfiguration();
118 if (!config.getManagedRepositoriesAsMap().containsKey( REPOID_INTERNAL ))
120 config.addManagedRepository( createManagedRepository( REPOID_INTERNAL, "Internal Test Repo", repoRootInternal ) );
122 saveConfiguration( archivaConfiguration );
124 CacheManager.getInstance().clearAll();
126 HttpUnitOptions.setExceptionsThrownOnErrorStatus( false );
128 sr = new ServletRunner( new File( "src/test/resources/WEB-INF/repository-servlet-security-test/web.xml" ) );
129 sr.registerServlet( "/repository/*", RepositoryServlet.class.getName() );
132 servletAuthControl = MockControl.createControl( ServletAuthenticator.class );
133 servletAuthControl.setDefaultMatcher( MockControl.ALWAYS_MATCHER );
134 servletAuth = (ServletAuthenticator) servletAuthControl.getMock();
137 MockClassControl.createControl( HttpBasicAuthentication.class, HttpBasicAuthentication.class.getMethods() );
138 httpAuthControl.setDefaultMatcher( MockControl.ALWAYS_MATCHER );
139 httpAuth = (HttpAuthenticator) httpAuthControl.getMock();
141 davSessionProvider = new ArchivaDavSessionProvider( servletAuth, httpAuth );
144 protected ManagedRepositoryConfiguration createManagedRepository( String id, String name, File location )
146 ManagedRepositoryConfiguration repo = new ManagedRepositoryConfiguration();
148 repo.setName( name );
149 repo.setLocation( location.getAbsolutePath() );
153 protected void saveConfiguration()
156 saveConfiguration( archivaConfiguration );
159 protected void saveConfiguration( ArchivaConfiguration archivaConfiguration )
162 archivaConfiguration.save( archivaConfiguration.getConfiguration() );
165 protected void setupCleanRepo( File repoRootDir )
168 FileUtils.deleteDirectory( repoRootDir );
169 if ( !repoRootDir.exists() )
171 repoRootDir.mkdirs();
177 public void tearDown()
190 if ( repoRootInternal.exists() )
192 FileUtils.deleteDirectory( repoRootInternal );
200 // test deploy with invalid user, and guest has no write access to repo
201 // 401 must be returned
203 public void testPutWithInvalidUserAndGuestHasNoWriteAccess()
206 setupCleanRepo( repoRootInternal );
208 String putUrl = "http://machine.com/repository/internal/path/to/artifact.jar";
209 InputStream is = getClass().getResourceAsStream( "/artifact.jar" );
210 assertNotNull( "artifact.jar inputstream", is );
212 WebRequest request = new PutMethodWebRequest( putUrl, is, "application/octet-stream" );
213 InvocationContext ic = sc.newInvocation( request );
214 servlet = (RepositoryServlet) ic.getServlet();
215 servlet.setDavSessionProvider( davSessionProvider );
217 AuthenticationResult result = new AuthenticationResult();
218 httpAuthControl.expectAndReturn( httpAuth.getAuthenticationResult( null, null ), result );
219 servletAuthControl.expectAndThrow( servletAuth.isAuthenticated( null, null ),
220 new AuthenticationException( "Authentication error" ) );
222 servletAuth.isAuthorized( "guest", "internal", ArchivaRoleConstants.OPERATION_REPOSITORY_UPLOAD );
223 servletAuthControl.setMatcher( MockControl.EQUALS_MATCHER );
224 servletAuthControl.setThrowable( new UnauthorizedException( "'guest' has no write access to repository" ) );
226 httpAuthControl.replay();
227 servletAuthControl.replay();
229 servlet.service( ic.getRequest(), ic.getResponse() );
231 httpAuthControl.verify();
232 servletAuthControl.verify();
234 // assertEquals(HttpServletResponse.SC_UNAUTHORIZED, response.getResponseCode());
237 // test deploy with invalid user, but guest has write access to repo
239 public void testPutWithInvalidUserAndGuestHasWriteAccess()
242 setupCleanRepo( repoRootInternal );
244 String putUrl = "http://machine.com/repository/internal/path/to/artifact.jar";
245 InputStream is = getClass().getResourceAsStream( "/artifact.jar" );
246 assertNotNull( "artifact.jar inputstream", is );
248 WebRequest request = new PutMethodWebRequest( putUrl, is, "application/octet-stream" );
250 InvocationContext ic = sc.newInvocation( request );
251 servlet = (RepositoryServlet) ic.getServlet();
252 servlet.setDavSessionProvider( davSessionProvider );
254 ArchivaDavResourceFactory archivaDavResourceFactory = (ArchivaDavResourceFactory) servlet.getResourceFactory();
255 archivaDavResourceFactory.setHttpAuth( httpAuth );
256 archivaDavResourceFactory.setServletAuth( servletAuth );
258 servlet.setResourceFactory( archivaDavResourceFactory );
260 AuthenticationResult result = new AuthenticationResult();
261 httpAuthControl.expectAndReturn( httpAuth.getAuthenticationResult( null, null ), result );
262 servletAuthControl.expectAndThrow( servletAuth.isAuthenticated( null, null ),
263 new AuthenticationException( "Authentication error" ) );
265 servletAuth.isAuthorized( "guest", "internal", ArchivaRoleConstants.OPERATION_REPOSITORY_UPLOAD );
266 servletAuthControl.setMatcher( MockControl.EQUALS_MATCHER );
267 servletAuthControl.setReturnValue( true );
269 // ArchivaDavResourceFactory#isAuthorized()
270 SecuritySession session = new DefaultSecuritySession();
271 httpAuthControl.expectAndReturn( httpAuth.getAuthenticationResult( null, null ), result );
272 httpAuthControl.expectAndReturn( httpAuth.getSecuritySession( ic.getRequest().getSession( true ) ), session );
273 servletAuthControl.expectAndThrow( servletAuth.isAuthenticated( null, result ),
274 new AuthenticationException( "Authentication error" ) );
276 httpAuthControl.expectAndReturn( httpAuth.getSessionUser( ic.getRequest().getSession() ), null );
278 // check if guest has write access
279 servletAuth.isAuthorized( "guest", "internal", ArchivaRoleConstants.OPERATION_REPOSITORY_UPLOAD );
280 servletAuthControl.setMatcher( MockControl.EQUALS_MATCHER );
281 servletAuthControl.setReturnValue( true );
283 httpAuthControl.replay();
284 servletAuthControl.replay();
286 servlet.service( ic.getRequest(), ic.getResponse() );
288 httpAuthControl.verify();
289 servletAuthControl.verify();
291 // assertEquals( HttpServletResponse.SC_CREATED, response.getResponseCode() );
294 // test deploy with a valid user with no write access
296 public void testPutWithValidUserWithNoWriteAccess()
299 setupCleanRepo( repoRootInternal );
301 String putUrl = "http://machine.com/repository/internal/path/to/artifact.jar";
302 InputStream is = getClass().getResourceAsStream( "/artifact.jar" );
303 assertNotNull( "artifact.jar inputstream", is );
305 WebRequest request = new PutMethodWebRequest( putUrl, is, "application/octet-stream" );
307 InvocationContext ic = sc.newInvocation( request );
308 servlet = (RepositoryServlet) ic.getServlet();
309 servlet.setDavSessionProvider( davSessionProvider );
311 ArchivaDavResourceFactory archivaDavResourceFactory = (ArchivaDavResourceFactory) servlet.getResourceFactory();
312 archivaDavResourceFactory.setHttpAuth( httpAuth );
313 archivaDavResourceFactory.setServletAuth( servletAuth );
314 servlet.setResourceFactory( archivaDavResourceFactory );
316 AuthenticationResult result = new AuthenticationResult();
317 httpAuthControl.expectAndReturn( httpAuth.getAuthenticationResult( null, null ), result );
318 servletAuthControl.expectAndReturn( servletAuth.isAuthenticated( null, null ), true );
320 // ArchivaDavResourceFactory#isAuthorized()
321 SecuritySession session = new DefaultSecuritySession();
322 httpAuthControl.expectAndReturn( httpAuth.getAuthenticationResult( null, null ), result );
323 httpAuthControl.expectAndReturn( httpAuth.getSecuritySession( ic.getRequest().getSession( true ) ), session );
324 httpAuthControl.expectAndReturn( httpAuth.getSessionUser( ic.getRequest().getSession() ), new SimpleUser() );
325 servletAuthControl.expectAndReturn( servletAuth.isAuthenticated( null, result ), true );
326 servletAuthControl.expectAndThrow(
327 servletAuth.isAuthorized( null, session, "internal",
328 ArchivaRoleConstants.OPERATION_REPOSITORY_UPLOAD ),
329 new UnauthorizedException( "User not authorized" ) );
331 httpAuthControl.replay();
332 servletAuthControl.replay();
334 servlet.service( ic.getRequest(), ic.getResponse() );
336 httpAuthControl.verify();
337 servletAuthControl.verify();
339 // assertEquals(HttpServletResponse.SC_UNAUTHORIZED, response.getResponseCode());
342 // test deploy with a valid user with write access
344 public void testPutWithValidUserWithWriteAccess()
347 setupCleanRepo( repoRootInternal );
348 assertTrue( repoRootInternal.exists() );
350 String putUrl = "http://machine.com/repository/internal/path/to/artifact.jar";
351 InputStream is = getClass().getResourceAsStream( "/artifact.jar" );
352 assertNotNull( "artifact.jar inputstream", is );
354 WebRequest request = new PutMethodWebRequest( putUrl, is, "application/octet-stream" );
356 InvocationContext ic = sc.newInvocation( request );
357 servlet = (RepositoryServlet) ic.getServlet();
358 servlet.setDavSessionProvider( davSessionProvider );
360 ArchivaDavResourceFactory archivaDavResourceFactory = (ArchivaDavResourceFactory) servlet.getResourceFactory();
361 archivaDavResourceFactory.setHttpAuth( httpAuth );
362 archivaDavResourceFactory.setServletAuth( servletAuth );
364 TestAuditListener listener = new TestAuditListener();
365 archivaDavResourceFactory.addAuditListener( listener );
366 servlet.setResourceFactory( archivaDavResourceFactory );
368 AuthenticationResult result = new AuthenticationResult();
369 httpAuthControl.expectAndReturn( httpAuth.getAuthenticationResult( null, null ), result );
370 servletAuthControl.expectAndReturn( servletAuth.isAuthenticated( null, null ), true );
372 User user = new SimpleUser();
373 user.setUsername( "admin" );
375 // ArchivaDavResourceFactory#isAuthorized()
376 SecuritySession session = new DefaultSecuritySession();
377 httpAuthControl.expectAndReturn( httpAuth.getAuthenticationResult( null, null ), result );
378 httpAuthControl.expectAndReturn( httpAuth.getSecuritySession( ic.getRequest().getSession( true ) ), session );
379 httpAuthControl.expectAndReturn( httpAuth.getSessionUser( ic.getRequest().getSession() ), user );
380 servletAuthControl.expectAndReturn( servletAuth.isAuthenticated( null, result ), true );
381 servletAuthControl.expectAndReturn(
382 servletAuth.isAuthorized( null, session, "internal",
383 ArchivaRoleConstants.OPERATION_REPOSITORY_UPLOAD ),
386 httpAuthControl.replay();
387 servletAuthControl.replay();
389 servlet.service( ic.getRequest(), ic.getResponse() );
391 httpAuthControl.verify();
392 servletAuthControl.verify();
394 // assertEquals(HttpServletResponse.SC_CREATED, response.getResponseCode());
396 assertEquals( "admin", listener.getEvents().get( 0 ).getUserId() );
399 // test get with invalid user, and guest has read access to repo
401 public void testGetWithInvalidUserAndGuestHasReadAccess()
404 String commonsLangJar = "commons-lang/commons-lang/2.1/commons-lang-2.1.jar";
405 String expectedArtifactContents = "dummy-commons-lang-artifact";
407 File artifactFile = new File( repoRootInternal, commonsLangJar );
408 artifactFile.getParentFile().mkdirs();
410 FileUtils.writeStringToFile( artifactFile, expectedArtifactContents, null );
412 WebRequest request = new GetMethodWebRequest( "http://machine.com/repository/internal/" + commonsLangJar );
413 InvocationContext ic = sc.newInvocation( request );
414 servlet = (RepositoryServlet) ic.getServlet();
415 servlet.setDavSessionProvider( davSessionProvider );
417 ArchivaDavResourceFactory archivaDavResourceFactory = (ArchivaDavResourceFactory) servlet.getResourceFactory();
418 archivaDavResourceFactory.setHttpAuth( httpAuth );
419 archivaDavResourceFactory.setServletAuth( servletAuth );
421 servlet.setResourceFactory( archivaDavResourceFactory );
423 AuthenticationResult result = new AuthenticationResult();
424 httpAuthControl.expectAndReturn( httpAuth.getAuthenticationResult( null, null ), result );
425 servletAuthControl.expectAndThrow( servletAuth.isAuthenticated( null, null ),
426 new AuthenticationException( "Authentication error" ) );
427 servletAuthControl.expectAndReturn(
428 servletAuth.isAuthorized( "guest", "internal",
429 ArchivaRoleConstants.OPERATION_REPOSITORY_ACCESS ),
432 // ArchivaDavResourceFactory#isAuthorized()
433 SecuritySession session = new DefaultSecuritySession();
434 httpAuthControl.expectAndReturn( httpAuth.getAuthenticationResult( null, null ), result );
435 httpAuthControl.expectAndReturn( httpAuth.getSecuritySession( ic.getRequest().getSession( true ) ), session );
436 httpAuthControl.expectAndReturn( httpAuth.getSessionUser( ic.getRequest().getSession() ), null );
437 servletAuthControl.expectAndReturn( servletAuth.isAuthenticated( null, result ), true );
438 servletAuthControl.expectAndReturn(
439 servletAuth.isAuthorized( null, session, "internal",
440 ArchivaRoleConstants.OPERATION_REPOSITORY_UPLOAD ),
443 httpAuthControl.replay();
444 servletAuthControl.replay();
446 WebResponse response = sc.getResponse( request );
448 httpAuthControl.verify();
449 servletAuthControl.verify();
451 assertEquals( HttpServletResponse.SC_OK, response.getResponseCode() );
452 assertEquals( "Expected file contents", expectedArtifactContents, response.getText() );
455 // test get with invalid user, and guest has no read access to repo
457 public void testGetWithInvalidUserAndGuestHasNoReadAccess()
460 String commonsLangJar = "commons-lang/commons-lang/2.1/commons-lang-2.1.jar";
461 String expectedArtifactContents = "dummy-commons-lang-artifact";
463 File artifactFile = new File( repoRootInternal, commonsLangJar );
464 artifactFile.getParentFile().mkdirs();
466 FileUtils.writeStringToFile( artifactFile, expectedArtifactContents, null );
468 WebRequest request = new GetMethodWebRequest( "http://machine.com/repository/internal/" + commonsLangJar );
469 InvocationContext ic = sc.newInvocation( request );
470 servlet = (RepositoryServlet) ic.getServlet();
471 servlet.setDavSessionProvider( davSessionProvider );
473 AuthenticationResult result = new AuthenticationResult();
474 httpAuthControl.expectAndReturn( httpAuth.getAuthenticationResult( null, null ), result );
475 servletAuthControl.expectAndThrow( servletAuth.isAuthenticated( null, null ),
476 new AuthenticationException( "Authentication error" ) );
477 servletAuthControl.expectAndReturn(
478 servletAuth.isAuthorized( "guest", "internal",
479 ArchivaRoleConstants.OPERATION_REPOSITORY_ACCESS ),
482 httpAuthControl.replay();
483 servletAuthControl.replay();
485 WebResponse response = sc.getResponse( request );
487 httpAuthControl.verify();
488 servletAuthControl.verify();
490 assertEquals( HttpServletResponse.SC_UNAUTHORIZED, response.getResponseCode() );
493 // test get with valid user with read access to repo
495 public void testGetWithAValidUserWithReadAccess()
498 String commonsLangJar = "commons-lang/commons-lang/2.1/commons-lang-2.1.jar";
499 String expectedArtifactContents = "dummy-commons-lang-artifact";
501 File artifactFile = new File( repoRootInternal, commonsLangJar );
502 artifactFile.getParentFile().mkdirs();
504 FileUtils.writeStringToFile( artifactFile, expectedArtifactContents, null );
506 WebRequest request = new GetMethodWebRequest( "http://machine.com/repository/internal/" + commonsLangJar );
507 InvocationContext ic = sc.newInvocation( request );
508 servlet = (RepositoryServlet) ic.getServlet();
509 servlet.setDavSessionProvider( davSessionProvider );
511 ArchivaDavResourceFactory archivaDavResourceFactory = (ArchivaDavResourceFactory) servlet.getResourceFactory();
512 archivaDavResourceFactory.setHttpAuth( httpAuth );
513 archivaDavResourceFactory.setServletAuth( servletAuth );
515 servlet.setResourceFactory( archivaDavResourceFactory );
517 AuthenticationResult result = new AuthenticationResult();
518 httpAuthControl.expectAndReturn( httpAuth.getAuthenticationResult( null, null ), result );
519 servletAuthControl.expectAndReturn( servletAuth.isAuthenticated( null, null ), true );
521 // ArchivaDavResourceFactory#isAuthorized()
522 SecuritySession session = new DefaultSecuritySession();
523 httpAuthControl.expectAndReturn( httpAuth.getAuthenticationResult( null, null ), result );
524 httpAuthControl.expectAndReturn( httpAuth.getSecuritySession( ic.getRequest().getSession( true ) ), session );
525 httpAuthControl.expectAndReturn( httpAuth.getSessionUser( ic.getRequest().getSession() ), new SimpleUser() );
526 servletAuthControl.expectAndReturn( servletAuth.isAuthenticated( null, result ), true );
527 servletAuthControl.expectAndReturn(
528 servletAuth.isAuthorized( null, session, "internal",
529 ArchivaRoleConstants.OPERATION_REPOSITORY_UPLOAD ),
532 httpAuthControl.replay();
533 servletAuthControl.replay();
535 WebResponse response = sc.getResponse( request );
537 httpAuthControl.verify();
538 servletAuthControl.verify();
540 assertEquals( HttpServletResponse.SC_OK, response.getResponseCode() );
541 assertEquals( "Expected file contents", expectedArtifactContents, response.getText() );
544 // test get with valid user with no read access to repo
546 public void testGetWithAValidUserWithNoReadAccess()
549 String commonsLangJar = "commons-lang/commons-lang/2.1/commons-lang-2.1.jar";
550 String expectedArtifactContents = "dummy-commons-lang-artifact";
552 File artifactFile = new File( repoRootInternal, commonsLangJar );
553 artifactFile.getParentFile().mkdirs();
555 FileUtils.writeStringToFile( artifactFile, expectedArtifactContents, null );
557 WebRequest request = new GetMethodWebRequest( "http://machine.com/repository/internal/" + commonsLangJar );
558 InvocationContext ic = sc.newInvocation( request );
559 servlet = (RepositoryServlet) ic.getServlet();
560 servlet.setDavSessionProvider( davSessionProvider );
562 ArchivaDavResourceFactory archivaDavResourceFactory = (ArchivaDavResourceFactory) servlet.getResourceFactory();
563 archivaDavResourceFactory.setHttpAuth( httpAuth );
564 archivaDavResourceFactory.setServletAuth( servletAuth );
566 servlet.setResourceFactory( archivaDavResourceFactory );
568 AuthenticationResult result = new AuthenticationResult();
569 httpAuthControl.expectAndReturn( httpAuth.getAuthenticationResult( null, null ), result );
570 servletAuthControl.expectAndReturn( servletAuth.isAuthenticated( null, null ), true );
572 // ArchivaDavResourceFactory#isAuthorized()
573 SecuritySession session = new DefaultSecuritySession();
574 httpAuthControl.expectAndReturn( httpAuth.getAuthenticationResult( null, null ), result );
575 httpAuthControl.expectAndReturn( httpAuth.getSecuritySession( ic.getRequest().getSession( true ) ), session );
576 httpAuthControl.expectAndReturn( httpAuth.getSessionUser( ic.getRequest().getSession() ), new SimpleUser() );
577 servletAuthControl.expectAndReturn( servletAuth.isAuthenticated( null, result ), true );
578 servletAuthControl.expectAndThrow(
579 servletAuth.isAuthorized( null, session, "internal",
580 ArchivaRoleConstants.OPERATION_REPOSITORY_UPLOAD ),
581 new UnauthorizedException( "User not authorized to read repository." ) );
583 httpAuthControl.replay();
584 servletAuthControl.replay();
586 WebResponse response = sc.getResponse( request );
588 httpAuthControl.verify();
589 servletAuthControl.verify();
591 assertEquals( HttpServletResponse.SC_UNAUTHORIZED, response.getResponseCode() );