@Override public FilterDirector handleResponse( HttpServletRequest request, ReadableHttpServletResponse response) { FilterDirector myDirector = new FilterDirectorImpl(); /// The WWW Authenticate header can be used to communicate to the client // (since we are a proxy) how to correctly authenticate itself final String wwwAuthenticateHeader = response.getHeader(CommonHttpHeader.WWW_AUTHENTICATE.toString()); switch (HttpStatusCode.fromInt(response.getStatus())) { // NOTE: We should only mutate the WWW-Authenticate header on a // 401 (unauthorized) or 403 (forbidden) response from the origin service case UNAUTHORIZED: case FORBIDDEN: myDirector = updateHttpResponse(myDirector, wwwAuthenticateHeader); break; case NOT_IMPLEMENTED: if ((!StringUtilities.isBlank(wwwAuthenticateHeader) && wwwAuthenticateHeader.contains("Delegated"))) { myDirector.setResponseStatus(HttpStatusCode.INTERNAL_SERVER_ERROR); LOG.error( "Repose authentication component is configured as delegetable but origin service does not support delegated mode."); } else { myDirector.setResponseStatus(HttpStatusCode.NOT_IMPLEMENTED); } break; } return myDirector; }
@Test public void shouldModifyDelegatedWwwAuthenticateHeaderOn403() { when(response.getHeader(CommonHttpHeader.WWW_AUTHENTICATE.toString())) .thenReturn("Delegated"); when(response.getStatus()).thenReturn(403); final FilterDirector responseDirector = handler.handleResponse(request, response); final String expected = "Keystone uri=" + osauthConfig.getIdentityService().getUri(); assertEquals( "Auth component must pass invalid requests but process their responses", expected, responseDirector .responseHeaderManager() .headersToAdd() .get(CommonHttpHeader.WWW_AUTHENTICATE.toString()) .iterator() .next()); }
@Test public void shouldReturn501OnAuth501FailureWithDelegatedWwwAuthenticateHeaderNotSet() { when(response.getHeader(CommonHttpHeader.WWW_AUTHENTICATE.toString())) .thenReturn("Not-Delegate"); when(response.getStatus()).thenReturn(501); final FilterDirector responseDirector = handler.handleResponse(request, response); assertEquals( "Auth component must identify proxy auth failures", HttpStatusCode.NOT_IMPLEMENTED, responseDirector.getResponseStatus()); }
private FilterDirector updateHttpResponse(FilterDirector director, String wwwAuthenticateHeader) { // If in the case that the origin service supports delegated authentication // we should then communicate to the client how to authenticate with us if (!StringUtilities.isBlank(wwwAuthenticateHeader) && wwwAuthenticateHeader.contains("Delegated")) { final String replacementWwwAuthenticateHeader = getWWWAuthenticateHeaderContents(); director .responseHeaderManager() .putHeader( CommonHttpHeader.WWW_AUTHENTICATE.toString(), replacementWwwAuthenticateHeader); } else { // In the case where authentication has failed and we did not receive // a delegated WWW-Authenticate header, this means that our own authentication // with the origin service has failed and must then be communicated as // a 500 (internal server error) to the client director.setResponseStatus(HttpStatusCode.INTERNAL_SERVER_ERROR); } return director; }