From 474fa8b8e9996fd755c34648a38854e726b72246 Mon Sep 17 00:00:00 2001 From: Jan Bartel Date: Tue, 14 Apr 2020 12:49:22 +0200 Subject: [PATCH] Issue #4762 Request.authenticate must return true if already authenticated (#4763) Signed-off-by: Jan Bartel --- .../jetty/security/ConstraintTest.java | 19 +++++++++++++++++++ .../org/eclipse/jetty/server/Request.java | 19 ++++++++++++++++--- 2 files changed, 35 insertions(+), 3 deletions(-) diff --git a/jetty-security/src/test/java/org/eclipse/jetty/security/ConstraintTest.java b/jetty-security/src/test/java/org/eclipse/jetty/security/ConstraintTest.java index 2cb0382f3989..681bc802487b 100644 --- a/jetty-security/src/test/java/org/eclipse/jetty/security/ConstraintTest.java +++ b/jetty-security/src/test/java/org/eclipse/jetty/security/ConstraintTest.java @@ -1155,6 +1155,16 @@ public void testFormProgrammaticLoginLogout() throws Exception assertThat(response, startsWith("HTTP/1.1 200 OK")); assertThat(response, containsString("user=user0")); _server.stop(); + + //loginauth + _server.start(); + response = _connector.getResponse("GET /ctx/prog?action=loginauth HTTP/1.0\r\n\r\n"); + assertThat(response, startsWith("HTTP/1.1 200 OK")); + assertThat(response, containsString("userPrincipal=admin")); + assertThat(response, containsString("remoteUser=admin")); + assertThat(response, containsString("authType=API")); + assertThat(response, containsString("auth=true")); + _server.stop(); //Test constraint-based login with programmatic login/logout: // constraintlogin - perform constraint login, followed by programmatic login which should fail (already logged in) @@ -1692,6 +1702,15 @@ public void handle(String target, Request baseRequest, HttpServletRequest reques response.getWriter().println("user=" + request.getRemoteUser()); return; } + else if ("loginauth".equals(action)) + { + request.login("admin", "password"); + response.getWriter().println("userPrincipal=" + request.getUserPrincipal()); + response.getWriter().println("remoteUser=" + request.getRemoteUser()); + response.getWriter().println("authType=" + request.getAuthType()); + response.getWriter().println("auth=" + request.authenticate(response)); + return; + } else if ("login".equals(action)) { request.login("admin", "password"); diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/Request.java b/jetty-server/src/main/java/org/eclipse/jetty/server/Request.java index 0572a6abd164..689ecbd3270f 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/Request.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/Request.java @@ -2215,13 +2215,26 @@ public String toString() @Override public boolean authenticate(HttpServletResponse response) throws IOException, ServletException { + //if already authenticated, return true + if (getUserPrincipal() != null && getRemoteUser() != null && getAuthType() != null) + return true; + + //do the authentication if (_authentication instanceof Authentication.Deferred) { setAuthentication(((Authentication.Deferred)_authentication).authenticate(this, response)); - return !(_authentication instanceof Authentication.ResponseSent); } - response.sendError(HttpStatus.UNAUTHORIZED_401); - return false; + + //if the authentication did not succeed + if (_authentication instanceof Authentication.Deferred) + response.sendError(HttpStatus.UNAUTHORIZED_401); + + //if the authentication is incomplete, return false + if (!(_authentication instanceof Authentication.ResponseSent)) + return false; + + //something has gone wrong + throw new ServletException("Authentication failed"); } @Override