/**
   * 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);
  }
Пример #3
0
  @Test
  public void shouldUseDifferentBucketsWhenUsingValidPartitionKey() throws Exception {
    FakeTimeService time = new FakeTimeService(0);
    Expression<String> expr =
        Expression.valueOf("${matches(exchange.foo, 'bar-00') ?'bucket-00' :''}", String.class);
    ThrottlingFilter filter = new ThrottlingFilter(time, 1, duration("3 seconds"), expr);

    Handler handler = new ResponseHandler(Status.OK);

    // The time does not need to advance
    Exchange exchange = new Exchange();
    Promise<Response, NeverThrowsException> promise;

    exchange.put("foo", "bar-00");
    promise = filter.filter(exchange, new Request(), handler);
    assertThat(promise.get().getStatus()).isEqualTo(Status.OK);

    exchange.put("foo", "bar-00");
    promise = filter.filter(exchange, new Request(), handler);
    assertThat(promise.get().getStatus()).isEqualTo(Status.TOO_MANY_REQUESTS);

    exchange.put("foo", "bar-01");
    promise = filter.filter(exchange, new Request(), handler);
    assertThat(promise.get().getStatus()).isEqualTo(Status.OK);
  }
Пример #4
0
 static {
   try {
     DEFAULT_PARTITION_EXPR =
         Expression.valueOf(ThrottlingFilter.DEFAULT_PARTITION_KEY, String.class);
   } catch (ExpressionException e) {
     throw new ExceptionInInitializerError(e);
   }
 }
  @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);
  }
Пример #9
0
  @Test
  public void shouldUseDefaultValueWithExpressionEvaluatingNull() throws Exception {
    FakeTimeService time = new FakeTimeService(0);
    Expression<String> expr = Expression.valueOf("${exchange.bar}", String.class);
    ThrottlingFilter filter = new ThrottlingFilter(time, 1, duration("3 seconds"), expr);

    Handler handler = new ResponseHandler(Status.OK);

    // The time does not need to advance
    Exchange exchange = new Exchange();
    Promise<Response, NeverThrowsException> promise;

    promise = filter.filter(exchange, new Request(), handler);
    assertThat(promise.get().getStatus()).isEqualTo(Status.INTERNAL_SERVER_ERROR);
  }