From 40fd68b26476a57b4ea1e19c665ef121a9ef310d Mon Sep 17 00:00:00 2001 From: Jeremy Landis Date: Sat, 28 Jan 2017 23:01:15 -0500 Subject: [PATCH] WIP: Fix for #59. --- .../spi/NegotiateSecurityFilterProvider.java | 3 +++ .../waffle/mock/http/SimpleHttpResponse.java | 6 +++++ .../servlet/NegotiateSecurityFilterTest.java | 26 +++++++++++++++---- .../waffle/apache/MixedAuthenticator.java | 5 +++- .../waffle/apache/NegotiateAuthenticator.java | 5 +++- .../waffle/apache/MixedAuthenticator.java | 5 +++- .../waffle/apache/NegotiateAuthenticator.java | 5 +++- .../waffle/apache/MixedAuthenticator.java | 5 +++- .../waffle/apache/NegotiateAuthenticator.java | 5 +++- 9 files changed, 54 insertions(+), 11 deletions(-) diff --git a/Source/JNA/waffle-jna/src/main/java/waffle/servlet/spi/NegotiateSecurityFilterProvider.java b/Source/JNA/waffle-jna/src/main/java/waffle/servlet/spi/NegotiateSecurityFilterProvider.java index 9a053e43bb..d8fe62728b 100644 --- a/Source/JNA/waffle-jna/src/main/java/waffle/servlet/spi/NegotiateSecurityFilterProvider.java +++ b/Source/JNA/waffle-jna/src/main/java/waffle/servlet/spi/NegotiateSecurityFilterProvider.java @@ -151,6 +151,9 @@ public IWindowsIdentity doFilter(final HttpServletRequest request, final HttpSer if (securityContext.isContinue()) { response.setHeader("Connection", "keep-alive"); response.setStatus(HttpServletResponse.SC_UNAUTHORIZED); + final String body = "Unauthorized"; + response.getWriter().write(body); + response.setContentLength(body.length()); response.flushBuffer(); return null; } diff --git a/Source/JNA/waffle-tests/src/main/java/waffle/mock/http/SimpleHttpResponse.java b/Source/JNA/waffle-tests/src/main/java/waffle/mock/http/SimpleHttpResponse.java index 1156a5f492..49440a087d 100644 --- a/Source/JNA/waffle-tests/src/main/java/waffle/mock/http/SimpleHttpResponse.java +++ b/Source/JNA/waffle-tests/src/main/java/waffle/mock/http/SimpleHttpResponse.java @@ -218,4 +218,10 @@ public String getOutputText() { } return null; } + + @Override + public void setContentLength(int len) { + setHeader("Content-Length", Integer.toString(len)); + } + } diff --git a/Source/JNA/waffle-tests/src/test/java/waffle/servlet/NegotiateSecurityFilterTest.java b/Source/JNA/waffle-tests/src/test/java/waffle/servlet/NegotiateSecurityFilterTest.java index 1bdcbc426b..963bf16b47 100644 --- a/Source/JNA/waffle-tests/src/test/java/waffle/servlet/NegotiateSecurityFilterTest.java +++ b/Source/JNA/waffle-tests/src/test/java/waffle/servlet/NegotiateSecurityFilterTest.java @@ -149,7 +149,7 @@ void testChallengePOST() throws IOException, ServletException { this.filter.doFilter(request, response, null); Assertions.assertTrue(response.getHeader("WWW-Authenticate").startsWith(securityPackage + " ")); Assertions.assertEquals("keep-alive", response.getHeader("Connection")); - Assertions.assertEquals(2, response.getHeaderNamesSize()); + Assertions.assertEquals(3, response.getHeaderNamesSize()); Assertions.assertEquals(401, response.getStatus()); } finally { if (clientContext != null) { @@ -207,10 +207,26 @@ void testNegotiate() throws IOException, ServletException { break; } + Assertions.assertEquals(401, response.getStatus()); + + // security package requested is one negotiate continues with Assertions.assertTrue(response.getHeader("WWW-Authenticate").startsWith(securityPackage + " ")); + + // keep-alive, NTLM is a connection-oriented protocol Assertions.assertEquals("keep-alive", response.getHeader("Connection")); - Assertions.assertEquals(2, response.getHeaderNamesSize()); - Assertions.assertEquals(401, response.getStatus()); + + // Connection: keep-alive + // WWW-Authenticate: ... + // Content-Length: ... + Assertions.assertEquals(3, response.getHeaderNamesSize()); + + // response has a body and a content length (.NET clients require this) + int contentLength = Integer.parseInt(response.getHeader("Content-Length")); + Assertions.assertTrue(contentLength > 0); + String content = response.getOutputText(); + Assertions.assertEquals(contentLength, content.length()); + + // continue token final String continueToken = response.getHeader("WWW-Authenticate") .substring(securityPackage.length() + 1); final byte[] continueTokenBytes = Base64.getDecoder().decode(continueToken); @@ -287,7 +303,7 @@ void testChallengeNTLMPOST() throws IOException, ServletException { final String[] wwwAuthenticates = response.getHeaderValues("WWW-Authenticate"); Assertions.assertEquals(1, wwwAuthenticates.length); Assertions.assertTrue(wwwAuthenticates[0].startsWith("NTLM ")); - Assertions.assertEquals(2, response.getHeaderNamesSize()); + Assertions.assertEquals(3, response.getHeaderNamesSize()); Assertions.assertEquals("keep-alive", response.getHeader("Connection")); Assertions.assertEquals(401, response.getStatus()); } @@ -316,7 +332,7 @@ void testChallengeNTLMPUT() throws IOException, ServletException { final String[] wwwAuthenticates = response.getHeaderValues("WWW-Authenticate"); Assertions.assertEquals(1, wwwAuthenticates.length); Assertions.assertTrue(wwwAuthenticates[0].startsWith("NTLM ")); - Assertions.assertEquals(2, response.getHeaderNamesSize()); + Assertions.assertEquals(3, response.getHeaderNamesSize()); Assertions.assertEquals("keep-alive", response.getHeader("Connection")); Assertions.assertEquals(401, response.getStatus()); } diff --git a/Source/JNA/waffle-tomcat10/src/main/java/waffle/apache/MixedAuthenticator.java b/Source/JNA/waffle-tomcat10/src/main/java/waffle/apache/MixedAuthenticator.java index 4ff356cd29..fdf85d0526 100644 --- a/Source/JNA/waffle-tomcat10/src/main/java/waffle/apache/MixedAuthenticator.java +++ b/Source/JNA/waffle-tomcat10/src/main/java/waffle/apache/MixedAuthenticator.java @@ -179,7 +179,10 @@ private boolean negotiate(final Request request, final HttpServletResponse respo try { if (securityContext.isContinue() || ntlmPost) { response.setHeader("Connection", "keep-alive"); - response.sendError(HttpServletResponse.SC_UNAUTHORIZED); + response.setStatus(HttpServletResponse.SC_UNAUTHORIZED); + String body = "Unauthorized"; + response.getWriter().write(body); + response.setContentLength(body.length()); response.flushBuffer(); return false; } diff --git a/Source/JNA/waffle-tomcat10/src/main/java/waffle/apache/NegotiateAuthenticator.java b/Source/JNA/waffle-tomcat10/src/main/java/waffle/apache/NegotiateAuthenticator.java index 4a90582ffa..30d017c222 100644 --- a/Source/JNA/waffle-tomcat10/src/main/java/waffle/apache/NegotiateAuthenticator.java +++ b/Source/JNA/waffle-tomcat10/src/main/java/waffle/apache/NegotiateAuthenticator.java @@ -127,7 +127,10 @@ public boolean authenticate(final Request request, final HttpServletResponse res try { if (securityContext.isContinue()) { response.setHeader("Connection", "keep-alive"); - response.sendError(HttpServletResponse.SC_UNAUTHORIZED); + response.setStatus(HttpServletResponse.SC_UNAUTHORIZED); + final String body = "Unauthorized"; + response.getWriter().write(body); + response.setContentLength(body.length()); response.flushBuffer(); return false; } diff --git a/Source/JNA/waffle-tomcat85/src/main/java/waffle/apache/MixedAuthenticator.java b/Source/JNA/waffle-tomcat85/src/main/java/waffle/apache/MixedAuthenticator.java index 4b06a8ee79..efd55be344 100644 --- a/Source/JNA/waffle-tomcat85/src/main/java/waffle/apache/MixedAuthenticator.java +++ b/Source/JNA/waffle-tomcat85/src/main/java/waffle/apache/MixedAuthenticator.java @@ -179,7 +179,10 @@ private boolean negotiate(final Request request, final HttpServletResponse respo try { if (securityContext.isContinue() || ntlmPost) { response.setHeader("Connection", "keep-alive"); - response.sendError(HttpServletResponse.SC_UNAUTHORIZED); + response.setStatus(HttpServletResponse.SC_UNAUTHORIZED); + String body = "Unauthorized"; + response.getWriter().write(body); + response.setContentLength(body.length()); response.flushBuffer(); return false; } diff --git a/Source/JNA/waffle-tomcat85/src/main/java/waffle/apache/NegotiateAuthenticator.java b/Source/JNA/waffle-tomcat85/src/main/java/waffle/apache/NegotiateAuthenticator.java index 9141c8ab08..e2ec02846e 100644 --- a/Source/JNA/waffle-tomcat85/src/main/java/waffle/apache/NegotiateAuthenticator.java +++ b/Source/JNA/waffle-tomcat85/src/main/java/waffle/apache/NegotiateAuthenticator.java @@ -127,7 +127,10 @@ public boolean authenticate(final Request request, final HttpServletResponse res try { if (securityContext.isContinue()) { response.setHeader("Connection", "keep-alive"); - response.sendError(HttpServletResponse.SC_UNAUTHORIZED); + response.setStatus(HttpServletResponse.SC_UNAUTHORIZED); + final String body = "Unauthorized"; + response.getWriter().write(body); + response.setContentLength(body.length()); response.flushBuffer(); return false; } diff --git a/Source/JNA/waffle-tomcat9/src/main/java/waffle/apache/MixedAuthenticator.java b/Source/JNA/waffle-tomcat9/src/main/java/waffle/apache/MixedAuthenticator.java index 4b06a8ee79..efd55be344 100644 --- a/Source/JNA/waffle-tomcat9/src/main/java/waffle/apache/MixedAuthenticator.java +++ b/Source/JNA/waffle-tomcat9/src/main/java/waffle/apache/MixedAuthenticator.java @@ -179,7 +179,10 @@ private boolean negotiate(final Request request, final HttpServletResponse respo try { if (securityContext.isContinue() || ntlmPost) { response.setHeader("Connection", "keep-alive"); - response.sendError(HttpServletResponse.SC_UNAUTHORIZED); + response.setStatus(HttpServletResponse.SC_UNAUTHORIZED); + String body = "Unauthorized"; + response.getWriter().write(body); + response.setContentLength(body.length()); response.flushBuffer(); return false; } diff --git a/Source/JNA/waffle-tomcat9/src/main/java/waffle/apache/NegotiateAuthenticator.java b/Source/JNA/waffle-tomcat9/src/main/java/waffle/apache/NegotiateAuthenticator.java index 9141c8ab08..e2ec02846e 100644 --- a/Source/JNA/waffle-tomcat9/src/main/java/waffle/apache/NegotiateAuthenticator.java +++ b/Source/JNA/waffle-tomcat9/src/main/java/waffle/apache/NegotiateAuthenticator.java @@ -127,7 +127,10 @@ public boolean authenticate(final Request request, final HttpServletResponse res try { if (securityContext.isContinue()) { response.setHeader("Connection", "keep-alive"); - response.sendError(HttpServletResponse.SC_UNAUTHORIZED); + response.setStatus(HttpServletResponse.SC_UNAUTHORIZED); + final String body = "Unauthorized"; + response.getWriter().write(body); + response.setContentLength(body.length()); response.flushBuffer(); return false; }