@Test public void testHeadersAreRemoved() throws Exception { HttpBasicAuthFilter filter = new HttpBasicAuthFilter(null, null, failureHandler); filter.setCacheHeader(false); Exchange exchange = newExchange(); Request request = newRequest(); request.getHeaders().putSingle(AUTHORIZATION_HEADER, "Basic azerty"); doAnswer( new Answer<Promise<Response, NeverThrowsException>>() { @Override public Promise<Response, NeverThrowsException> answer( final InvocationOnMock invocation) throws Throwable { // Produce a valid response with an authentication challenge Response response = new Response(); response.setStatus(Status.OK); response.getHeaders().putSingle(AUTHENTICATE_HEADER, "Realm toto"); return Promises.newResultPromise(response); } }) .when(terminalHandler) .handle(eq(exchange), argThat(new AbsenceOfHeaderInRequest(AUTHORIZATION_HEADER))); Response response = filter.filter(exchange, request, terminalHandler).getOrThrow(); // Verify that the outgoing message has no authenticate header assertThat(response.getHeaders().get(AUTHENTICATE_HEADER)).isNull(); }
/** * 2 consecutive requests are sharing the same session. The first one should build and cache the * Authorization header after a round trip to the next handler (firstly answer with a challenge). * The second should simply re-use the cached value * * @throws Exception */ @Test public void tesAuthorizationHeaderCaching() throws Exception { HttpBasicAuthFilter filter = new HttpBasicAuthFilter( Expression.valueOf("bjensen", String.class), Expression.valueOf("hifalutin", String.class), failureHandler); filter.setCacheHeader(true); // No value cached for the first call // Subsequent invocations get the cached value when(session.get(endsWith(":userpass"))).thenReturn(null, INITIAL_CREDENTIALS); basicAuthServerAnswersUnauthorizedThenSuccess(INITIAL_CREDENTIALS); Exchange first = newExchange(); Request firstRequest = newRequest(); Response firstResponse = filter.filter(first, firstRequest, terminalHandler).getOrThrow(); Exchange second = newExchange(); Request secondRequest = newRequest(); Response secondResponse = filter.filter(second, secondRequest, terminalHandler).getOrThrow(); // Terminal handler should be called 3 times, not 4 verify(terminalHandler, times(3)).handle(any(Exchange.class), any(Request.class)); // Session should be updated with cached value verify(session).put(endsWith(":userpass"), eq(INITIAL_CREDENTIALS)); // Responses should be OK for all outgoing responses assertThat(firstResponse.getStatus()).isEqualTo(Status.OK); assertThat(secondResponse.getStatus()).isEqualTo(Status.OK); }
@Test public void testRefreshAuthenticationHeader() throws Exception { HttpBasicAuthFilter filter = new HttpBasicAuthFilter( Expression.valueOf("bjensen", String.class), Expression.valueOf("${exchange.password}", String.class), failureHandler); filter.setCacheHeader(true); // Mock cache content for credentials when(session.get(endsWith(":userpass"))) .thenReturn(null, INITIAL_CREDENTIALS, INITIAL_CREDENTIALS, REFRESHED_CREDENTIALS); // Scenario: // first request (cache the value after initial round-trip) // second request (cached value is OK) // third request (cached value is no longer valid, trigger a refresh) doAnswer(new UnauthorizedAnswer()) .doAnswer(new AuthorizedAnswer(INITIAL_CREDENTIALS)) .doAnswer(new AuthorizedAnswer(INITIAL_CREDENTIALS)) .doAnswer(new UnauthorizedAnswer()) .doAnswer(new AuthorizedAnswer(REFRESHED_CREDENTIALS)) .when(terminalHandler) .handle(any(Exchange.class), any(Request.class)); // Initial round-trip Exchange first = newExchange(); first.put("password", "hifalutin"); Response firstResponse = filter.filter(first, newRequest(), terminalHandler).getOrThrow(); // Usage of cached value Exchange second = newExchange(); Response secondResponse = filter.filter(second, newRequest(), terminalHandler).getOrThrow(); // Cached value is no longer valid, trigger a user/pass refresh Exchange third = newExchange(); third.put("password", "hifalutin2"); Response thirdResponse = filter.filter(third, newRequest(), terminalHandler).getOrThrow(); // Terminal handler should be called 5 times, not 6 // first: 2 times // second: 1 time // third: 2 times verify(terminalHandler, times(5)).handle(any(Exchange.class), any(Request.class)); // Session should be updated with cached value 2 times verify(session).put(endsWith(":userpass"), eq(INITIAL_CREDENTIALS)); verify(session).put(endsWith(":userpass"), eq(REFRESHED_CREDENTIALS)); // Responses should be OK for all outgoing responses assertThat(firstResponse.getStatus()).isEqualTo(Status.OK); assertThat(secondResponse.getStatus()).isEqualTo(Status.OK); assertThat(thirdResponse.getStatus()).isEqualTo(Status.OK); }
@Test public void testNominalInteraction() throws Exception { HttpBasicAuthFilter filter = new HttpBasicAuthFilter( Expression.valueOf("bjensen", String.class), Expression.valueOf("hifalutin", String.class), failureHandler); filter.setCacheHeader(false); basicAuthServerAnswersUnauthorizedThenSuccess(INITIAL_CREDENTIALS); Exchange exchange = newExchange(); Request request = newRequest(); Response response = filter.filter(exchange, request, terminalHandler).getOrThrow(); assertThat(response.getStatus()).isEqualTo(Status.OK); }
@Test(dataProvider = "invalidUserNames") public void testConformanceErrorIsProducedWhenUsernameContainsColon(final String username) throws Exception { HttpBasicAuthFilter filter = new HttpBasicAuthFilter( Expression.valueOf(username, String.class), Expression.valueOf("dont-care", String.class), failureHandler); filter.setCacheHeader(false); basicAuthServerAnswersUnauthorizedThenSuccess(INITIAL_CREDENTIALS); Response response = filter.filter(newExchange(), newRequest(), terminalHandler).get(); assertThat(response.getStatus()).isEqualTo(Status.INTERNAL_SERVER_ERROR); assertThat(response.getEntity().getString()) .contains("username must not contain a colon ':' character"); }
/** * If there is no credentials provided, the filter should not try to forward the request more than * once */ @Test public void testNoCredentialsProvided() throws Exception { HttpBasicAuthFilter filter = new HttpBasicAuthFilter( Expression.valueOf("${null}", String.class), Expression.valueOf("${null}", String.class), failureHandler); filter.setCacheHeader(false); // Always answer with 401 doAnswer(new UnauthorizedAnswer()) .when(terminalHandler) .handle(any(Exchange.class), any(Request.class)); Exchange exchange = newExchange(); Request request = newRequest(); filter.filter(exchange, request, terminalHandler); verify(terminalHandler, times(1)).handle(exchange, request); verify(failureHandler).handle(exchange, request); }
/** * If there are credentials but invalid ones (not accepted by the target application), this filter * should try 2 times: one with the old credential (or no credential if none are cached), and * another one with the refreshed credentials. */ @Test public void testInvalidCredentialsProvided() throws Exception { HttpBasicAuthFilter filter = new HttpBasicAuthFilter( Expression.valueOf("bjensen", String.class), Expression.valueOf("hifalutin", String.class), failureHandler); filter.setCacheHeader(false); // Always answer with 401 doAnswer(new UnauthorizedAnswer()) .when(terminalHandler) .handle(any(Exchange.class), any(Request.class)); Exchange exchange = newExchange(); Request request = newRequest(); filter.filter(exchange, request, terminalHandler); // if credentials were rejected all the times, the failure Handler is invoked verify(terminalHandler, times(2)).handle(exchange, request); verify(failureHandler).handle(exchange, request); }