This is an automated email from the ASF dual-hosted git repository.

markt pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/tomcat.git


The following commit(s) were added to refs/heads/main by this push:
     new 61419c2e68 Update Basic authentication to RFC 7617
61419c2e68 is described below

commit 61419c2e68842690259aabc9d3dfea5575ef0c64
Author: Mark Thomas <ma...@apache.org>
AuthorDate: Tue Apr 16 10:34:56 2024 +0100

    Update Basic authentication to RFC 7617
---
 .../catalina/authenticator/BasicAuthenticator.java |  41 ++----
 .../authenticator/TestBasicAuthParser.java         | 153 ++++++++-------------
 webapps/docs/changelog.xml                         |   5 +
 webapps/docs/config/valve.xml                      |   6 -
 4 files changed, 69 insertions(+), 136 deletions(-)

diff --git a/java/org/apache/catalina/authenticator/BasicAuthenticator.java 
b/java/org/apache/catalina/authenticator/BasicAuthenticator.java
index 168d7505f6..28114ec24a 100644
--- a/java/org/apache/catalina/authenticator/BasicAuthenticator.java
+++ b/java/org/apache/catalina/authenticator/BasicAuthenticator.java
@@ -20,6 +20,7 @@ import java.io.IOException;
 import java.nio.charset.Charset;
 import java.nio.charset.StandardCharsets;
 import java.security.Principal;
+import java.util.Base64;
 
 import jakarta.servlet.http.HttpServletRequest;
 import jakarta.servlet.http.HttpServletResponse;
@@ -29,7 +30,6 @@ import org.apache.juli.logging.Log;
 import org.apache.juli.logging.LogFactory;
 import org.apache.tomcat.util.buf.ByteChunk;
 import org.apache.tomcat.util.buf.MessageBytes;
-import org.apache.tomcat.util.codec.binary.Base64;
 
 /**
  * An <b>Authenticator</b> and <b>Valve</b> implementation of HTTP BASIC 
Authentication, as outlined in RFC 7617: "The
@@ -43,7 +43,6 @@ public class BasicAuthenticator extends AuthenticatorBase {
 
     private Charset charset = StandardCharsets.UTF_8;
     private String charsetString = "UTF-8";
-    private boolean trimCredentials = true;
 
 
     public String getCharset() {
@@ -64,16 +63,6 @@ public class BasicAuthenticator extends AuthenticatorBase {
     }
 
 
-    public boolean getTrimCredentials() {
-        return trimCredentials;
-    }
-
-
-    public void setTrimCredentials(boolean trimCredentials) {
-        this.trimCredentials = trimCredentials;
-    }
-
-
     @Override
     protected boolean doAuthenticate(Request request, HttpServletResponse 
response) throws IOException {
 
@@ -89,7 +78,7 @@ public class BasicAuthenticator extends AuthenticatorBase {
             ByteChunk authorizationBC = authorization.getByteChunk();
             BasicCredentials credentials = null;
             try {
-                credentials = new BasicCredentials(authorizationBC, charset, 
getTrimCredentials());
+                credentials = new BasicCredentials(authorizationBC, charset);
                 String username = credentials.getUsername();
                 String password = credentials.getPassword();
 
@@ -145,7 +134,6 @@ public class BasicAuthenticator extends AuthenticatorBase {
         private static final String METHOD = "basic ";
 
         private final Charset charset;
-        private final boolean trimCredentials;
         private final ByteChunk authorization;
         private final int initialOffset;
         private int base64blobOffset;
@@ -155,21 +143,17 @@ public class BasicAuthenticator extends AuthenticatorBase 
{
         private String password = null;
 
         /**
-         * Parse the HTTP Authorization header for BASIC authentication as per 
RFC 2617 section 2, and the Base64
-         * encoded credentials as per RFC 2045 section 6.8.
+         * Parse the HTTP Authorization header for BASIC authentication as per 
RFC 7617.
          *
          * @param input           The header value to parse in-place
          * @param charset         The character set to use to convert the 
bytes to a string
-         * @param trimCredentials Should leading and trailing whitespace be 
removed from the parsed credentials
          *
-         * @throws IllegalArgumentException If the header does not conform to 
RFC 2617
+         * @throws IllegalArgumentException If the header does not conform to 
RFC 7617
          */
-        public BasicCredentials(ByteChunk input, Charset charset, boolean 
trimCredentials)
-                throws IllegalArgumentException {
+        public BasicCredentials(ByteChunk input, Charset charset) throws 
IllegalArgumentException {
             authorization = input;
             initialOffset = input.getOffset();
             this.charset = charset;
-            this.trimCredentials = trimCredentials;
 
             parseMethod();
             byte[] decoded = parseBase64();
@@ -196,7 +180,8 @@ public class BasicAuthenticator extends AuthenticatorBase {
         }
 
         /*
-         * The authorization method string is case-insensitive and must hae at 
least one space character as a delimiter.
+         * The authorization method string is case-insensitive and must have 
at exactly one space character as a
+         * delimiter.
          */
         private void parseMethod() throws IllegalArgumentException {
             if (authorization.startsWithIgnoreCase(METHOD, 0)) {
@@ -215,7 +200,9 @@ public class BasicAuthenticator extends AuthenticatorBase {
          * surrounding white space.
          */
         private byte[] parseBase64() throws IllegalArgumentException {
-            byte[] decoded = Base64.decodeBase64(authorization.getBuffer(), 
base64blobOffset, base64blobLength);
+            byte[] encoded = new byte[base64blobLength];
+            System.arraycopy(authorization.getBuffer(), base64blobOffset, 
encoded, 0, base64blobLength);
+            byte[] decoded = Base64.getDecoder().decode(encoded);
             // restore original offset
             authorization.setOffset(initialOffset);
             if (decoded == null) {
@@ -244,14 +231,6 @@ public class BasicAuthenticator extends AuthenticatorBase {
             } else {
                 username = new String(decoded, 0, colon, charset);
                 password = new String(decoded, colon + 1, decoded.length - 
colon - 1, charset);
-                // tolerate surplus white space around credentials
-                if (password.length() > 1 && trimCredentials) {
-                    password = password.trim();
-                }
-            }
-            // tolerate surplus white space around credentials
-            if (username.length() > 1 && trimCredentials) {
-                username = username.trim();
             }
         }
     }
diff --git a/test/org/apache/catalina/authenticator/TestBasicAuthParser.java 
b/test/org/apache/catalina/authenticator/TestBasicAuthParser.java
index d1dfe31f0b..36496b8f1b 100644
--- a/test/org/apache/catalina/authenticator/TestBasicAuthParser.java
+++ b/test/org/apache/catalina/authenticator/TestBasicAuthParser.java
@@ -18,12 +18,12 @@ package org.apache.catalina.authenticator;
 
 import java.io.IOException;
 import java.nio.charset.StandardCharsets;
+import java.util.Base64;
 
 import org.junit.Assert;
 import org.junit.Test;
 
 import org.apache.tomcat.util.buf.ByteChunk;
-import org.apache.tomcat.util.codec.binary.Base64;
 
 /**
  * Test the BasicAuthenticator's BasicCredentials inner class and the
@@ -45,7 +45,7 @@ public class TestBasicAuthParser {
                 new BasicAuthHeader(NICE_METHOD, USER_NAME, PASSWORD);
         BasicAuthenticator.BasicCredentials credentials =
                 new BasicAuthenticator.BasicCredentials(
-                AUTH_HEADER.getHeader(), StandardCharsets.UTF_8, true);
+                AUTH_HEADER.getHeader(), StandardCharsets.UTF_8);
         Assert.assertEquals(USER_NAME, credentials.getUsername());
         Assert.assertEquals(PASSWORD, credentials.getPassword());
     }
@@ -56,7 +56,7 @@ public class TestBasicAuthParser {
                 new BasicAuthHeader(NICE_METHOD, USER_NAME, null);
         BasicAuthenticator.BasicCredentials credentials =
                 new BasicAuthenticator.BasicCredentials(
-                AUTH_HEADER.getHeader(), StandardCharsets.UTF_8, true);
+                AUTH_HEADER.getHeader(), StandardCharsets.UTF_8);
         Assert.assertEquals(USER_NAME, credentials.getUsername());
         Assert.assertNull(credentials.getPassword());
     }
@@ -68,7 +68,7 @@ public class TestBasicAuthParser {
                 new BasicAuthHeader(NICE_METHOD, BASE64_CRIB);
         BasicAuthenticator.BasicCredentials credentials =
                 new BasicAuthenticator.BasicCredentials(
-                AUTH_HEADER.getHeader(), StandardCharsets.UTF_8, true);
+                AUTH_HEADER.getHeader(), StandardCharsets.UTF_8);
         Assert.assertEquals(USER_NAME, credentials.getUsername());
         Assert.assertEquals(PASSWORD, credentials.getPassword());
     }
@@ -80,7 +80,7 @@ public class TestBasicAuthParser {
                 new BasicAuthHeader(NICE_METHOD, BASE64_CRIB);
         BasicAuthenticator.BasicCredentials credentials =
                 new BasicAuthenticator.BasicCredentials(
-                AUTH_HEADER.getHeader(), StandardCharsets.UTF_8, true);
+                AUTH_HEADER.getHeader(), StandardCharsets.UTF_8);
         Assert.assertEquals(USER_NAME, credentials.getUsername());
         Assert.assertNull(credentials.getPassword());
     }
@@ -93,34 +93,24 @@ public class TestBasicAuthParser {
                 new BasicAuthHeader(NICE_METHOD, BASE64_CRIB);
         BasicAuthenticator.BasicCredentials credentials =
                 new BasicAuthenticator.BasicCredentials(
-                AUTH_HEADER.getHeader(), StandardCharsets.UTF_8, true);
+                AUTH_HEADER.getHeader(), StandardCharsets.UTF_8);
         Assert.assertEquals(USER_NAME, credentials.getUsername());
         Assert.assertEquals(PASSWORD1, credentials.getPassword());
     }
 
     /*
-     * RFC 2045 says the Base64 encoded string should be represented
-     * as lines of no more than 76 characters. However, RFC 2617
-     * says a base64-user-pass token is not limited to 76 char/line.
-     * It also says all line breaks, including mandatory ones,
-     * should be ignored during decoding.
-     * This test case has a line break in the Base64 string.
-     * (See also testGoodCribBase64Big below).
+     * Line breaks are not permitted inside the base64 encoded value.
      */
-    @Test
-    public void testGoodCribLineWrap() throws Exception {
-        final String USER_LONG = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
-                + "abcdefghijklmnopqrstuvwxyz0123456789+/AAAABBBBCCCC"
-                + "DDDD";                   // 80 characters
+    @Test(expected=IllegalArgumentException.class)
+    public void testLineWrap() throws Exception {
         final String BASE64_CRIB = "QUJDREVGR0hJSktMTU5PUFFSU1RVVldY"
                 + "WVphYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5ejAxMjM0"
                 + "\n" + "NTY3ODkrL0FBQUFCQkJCQ0NDQ0REREQ=";
-        final BasicAuthHeader AUTH_HEADER =
-                new BasicAuthHeader(NICE_METHOD, BASE64_CRIB);
+        final BasicAuthHeader AUTH_HEADER = new BasicAuthHeader(NICE_METHOD, 
BASE64_CRIB);
+        @SuppressWarnings("unused")
         BasicAuthenticator.BasicCredentials credentials =
                 new BasicAuthenticator.BasicCredentials(
-                AUTH_HEADER.getHeader(), StandardCharsets.UTF_8, true);
-        Assert.assertEquals(USER_LONG, credentials.getUsername());
+                AUTH_HEADER.getHeader(), StandardCharsets.UTF_8);
     }
 
     /*
@@ -141,7 +131,7 @@ public class TestBasicAuthParser {
                 new BasicAuthHeader(NICE_METHOD, BASE64_CRIB);
         BasicAuthenticator.BasicCredentials credentials =
                 new BasicAuthenticator.BasicCredentials(
-                AUTH_HEADER.getHeader(), StandardCharsets.UTF_8, true);
+                AUTH_HEADER.getHeader(), StandardCharsets.UTF_8);
         Assert.assertEquals(USER_LONG, credentials.getUsername());
     }
 
@@ -157,7 +147,7 @@ public class TestBasicAuthParser {
                 new BasicAuthHeader(METHOD, USER_NAME, PASSWORD);
         BasicAuthenticator.BasicCredentials credentials =
                 new BasicAuthenticator.BasicCredentials(
-                AUTH_HEADER.getHeader(), StandardCharsets.UTF_8, true);
+                AUTH_HEADER.getHeader(), StandardCharsets.UTF_8);
         Assert.assertEquals(USER_NAME, credentials.getUsername());
         Assert.assertEquals(PASSWORD, credentials.getPassword());
     }
@@ -172,26 +162,19 @@ public class TestBasicAuthParser {
                 new BasicAuthHeader(METHOD, USER_NAME, PASSWORD);
         @SuppressWarnings("unused")
         BasicAuthenticator.BasicCredentials credentials =
-                new 
BasicAuthenticator.BasicCredentials(AUTH_HEADER.getHeader(), 
StandardCharsets.UTF_8, true);
+                new 
BasicAuthenticator.BasicCredentials(AUTH_HEADER.getHeader(), 
StandardCharsets.UTF_8);
     }
 
     /*
-     * Confirm the Basic parser tolerates excess white space after
-     * the authentication method.
-     *
-     * RFC2617 does not define the separation syntax between the auth-scheme
-     * and basic-credentials tokens. Tomcat tolerates any amount of white
-     * (within the limits of HTTP header sizes).
+     * Confirm the Basic parser allows exactly one space after the 
authentication method.
      */
-    @Test
+    @Test(expected=IllegalArgumentException.class)
     public void testAuthMethodExtraLeadingSpace() throws Exception {
         final BasicAuthHeader AUTH_HEADER =
                 new BasicAuthHeader(NICE_METHOD + " ", USER_NAME, PASSWORD);
+        @SuppressWarnings("unused")
         final BasicAuthenticator.BasicCredentials credentials =
-                new BasicAuthenticator.BasicCredentials(
-                AUTH_HEADER.getHeader(), StandardCharsets.UTF_8, true);
-        Assert.assertEquals(USER_NAME, credentials.getUsername());
-        Assert.assertEquals(PASSWORD, credentials.getPassword());
+                new 
BasicAuthenticator.BasicCredentials(AUTH_HEADER.getHeader(), 
StandardCharsets.UTF_8);
     }
 
 
@@ -205,7 +188,7 @@ public class TestBasicAuthParser {
                 new BasicAuthHeader(NICE_METHOD, USER_NAME, PWD_WRONG);
         BasicAuthenticator.BasicCredentials credentials =
                 new BasicAuthenticator.BasicCredentials(
-                AUTH_HEADER.getHeader(), StandardCharsets.UTF_8, true);
+                AUTH_HEADER.getHeader(), StandardCharsets.UTF_8);
         Assert.assertEquals(USER_NAME, credentials.getUsername());
         Assert.assertNotSame(PASSWORD, credentials.getPassword());
     }
@@ -217,7 +200,7 @@ public class TestBasicAuthParser {
                 new BasicAuthHeader(NICE_METHOD, EMPTY_USER_NAME, PASSWORD);
         BasicAuthenticator.BasicCredentials credentials =
                 new BasicAuthenticator.BasicCredentials(
-                AUTH_HEADER.getHeader(), StandardCharsets.UTF_8, true);
+                AUTH_HEADER.getHeader(), StandardCharsets.UTF_8);
         Assert.assertEquals(EMPTY_USER_NAME, credentials.getUsername());
         Assert.assertEquals(PASSWORD, credentials.getPassword());
     }
@@ -229,7 +212,7 @@ public class TestBasicAuthParser {
                 new BasicAuthHeader(NICE_METHOD, SHORT_USER_NAME, PASSWORD);
         BasicAuthenticator.BasicCredentials credentials =
                 new BasicAuthenticator.BasicCredentials(
-                AUTH_HEADER.getHeader(), StandardCharsets.UTF_8, true);
+                AUTH_HEADER.getHeader(), StandardCharsets.UTF_8);
         Assert.assertEquals(SHORT_USER_NAME, credentials.getUsername());
         Assert.assertEquals(PASSWORD, credentials.getPassword());
     }
@@ -241,7 +224,7 @@ public class TestBasicAuthParser {
                 new BasicAuthHeader(NICE_METHOD, USER_NAME, SHORT_PASSWORD);
         BasicAuthenticator.BasicCredentials credentials =
                 new BasicAuthenticator.BasicCredentials(
-                AUTH_HEADER.getHeader(), StandardCharsets.UTF_8, true);
+                AUTH_HEADER.getHeader(), StandardCharsets.UTF_8);
         Assert.assertEquals(USER_NAME, credentials.getUsername());
         Assert.assertEquals(SHORT_PASSWORD, credentials.getPassword());
     }
@@ -253,7 +236,7 @@ public class TestBasicAuthParser {
                 new BasicAuthHeader(NICE_METHOD, USER_NAME, PASSWORD_SPACE);
         BasicAuthenticator.BasicCredentials credentials =
                 new BasicAuthenticator.BasicCredentials(
-                AUTH_HEADER.getHeader(), StandardCharsets.UTF_8, true);
+                AUTH_HEADER.getHeader(), StandardCharsets.UTF_8);
         Assert.assertEquals(USER_NAME, credentials.getUsername());
         Assert.assertEquals(PASSWORD_SPACE, credentials.getPassword());
     }
@@ -265,7 +248,7 @@ public class TestBasicAuthParser {
                 new BasicAuthHeader(NICE_METHOD, USER_NAME, PASSWORD_COLON);
         BasicAuthenticator.BasicCredentials credentials =
                 new BasicAuthenticator.BasicCredentials(
-                AUTH_HEADER.getHeader(), StandardCharsets.UTF_8, true);
+                AUTH_HEADER.getHeader(), StandardCharsets.UTF_8);
         Assert.assertEquals(USER_NAME, credentials.getUsername());
         Assert.assertEquals(PASSWORD_COLON, credentials.getPassword());
     }
@@ -277,7 +260,7 @@ public class TestBasicAuthParser {
                 new BasicAuthHeader(NICE_METHOD, USER_NAME, PASSWORD_COLON);
         BasicAuthenticator.BasicCredentials credentials =
                 new BasicAuthenticator.BasicCredentials(
-                AUTH_HEADER.getHeader(), StandardCharsets.UTF_8, true);
+                AUTH_HEADER.getHeader(), StandardCharsets.UTF_8);
         Assert.assertEquals(USER_NAME, credentials.getUsername());
         Assert.assertEquals(PASSWORD_COLON, credentials.getPassword());
     }
@@ -289,36 +272,24 @@ public class TestBasicAuthParser {
                 new BasicAuthHeader(NICE_METHOD, USER_NAME, PASSWORD_COLON);
         BasicAuthenticator.BasicCredentials credentials =
                 new BasicAuthenticator.BasicCredentials(
-                AUTH_HEADER.getHeader(), StandardCharsets.UTF_8, true);
+                AUTH_HEADER.getHeader(), StandardCharsets.UTF_8);
         Assert.assertEquals(USER_NAME, credentials.getUsername());
         Assert.assertEquals(PASSWORD_COLON, credentials.getPassword());
     }
 
     /*
-     * Confirm the Basic parser tolerates excess white space after
-     * the base64 blob.
-     *
-     * RFC2617 does not define this case, but asks servers to be
-     * tolerant of this kind of client deviation.
+     * Confirm the Basic parser does not tolerate excess white space after the 
base64 blob.
      */
-    @Test
+    @Test(expected=IllegalArgumentException.class)
     public void testAuthMethodExtraTrailingSpace() throws Exception {
-        final BasicAuthHeader AUTH_HEADER =
-                new BasicAuthHeader(NICE_METHOD, USER_NAME, PASSWORD, "    ");
+        final BasicAuthHeader AUTH_HEADER = new BasicAuthHeader(NICE_METHOD, 
USER_NAME, PASSWORD, "    ");
+        @SuppressWarnings("unused")
         BasicAuthenticator.BasicCredentials credentials =
-                new BasicAuthenticator.BasicCredentials(
-                AUTH_HEADER.getHeader(), StandardCharsets.UTF_8, true);
-        Assert.assertEquals(USER_NAME, credentials.getUsername());
-        Assert.assertEquals(PASSWORD, credentials.getPassword());
+                new 
BasicAuthenticator.BasicCredentials(AUTH_HEADER.getHeader(), 
StandardCharsets.UTF_8);
     }
 
     /*
-     * Confirm the Basic parser tolerates excess white space around
-     * the username inside the base64 blob.
-     *
-     * RFC2617 does not define the separation syntax between the auth-scheme
-     * and basic-credentials tokens. Tomcat should tolerate any reasonable
-     * amount of white space.
+     * Confirm the Basic parser does not tolerate excess white space around 
the username inside the base64 blob.
      */
     @Test
     public void testUserExtraSpace() throws Exception {
@@ -326,18 +297,14 @@ public class TestBasicAuthParser {
                 new BasicAuthHeader(NICE_METHOD, " " + USER_NAME + " ", 
PASSWORD);
         BasicAuthenticator.BasicCredentials credentials =
                 new BasicAuthenticator.BasicCredentials(
-                AUTH_HEADER.getHeader(), StandardCharsets.UTF_8, true);
-        Assert.assertEquals(USER_NAME, credentials.getUsername());
+                AUTH_HEADER.getHeader(), StandardCharsets.UTF_8);
+        Assert.assertNotEquals(USER_NAME, credentials.getUsername());
+        Assert.assertEquals(USER_NAME, credentials.getUsername().trim());
         Assert.assertEquals(PASSWORD, credentials.getPassword());
     }
 
     /*
-     * Confirm the Basic parser tolerates excess white space around
-     * the username within the base64 blob.
-     *
-     * RFC2617 does not define the separation syntax between the auth-scheme
-     * and basic-credentials tokens. Tomcat should tolerate any reasonable
-     * amount of white space.
+     * Confirm the Basic parser does not tolerate excess white space around 
the password within the base64 blob.
      */
     @Test
     public void testPasswordExtraSpace() throws Exception {
@@ -345,9 +312,10 @@ public class TestBasicAuthParser {
                 new BasicAuthHeader(NICE_METHOD, USER_NAME, " " + PASSWORD + " 
");
         BasicAuthenticator.BasicCredentials credentials =
                 new BasicAuthenticator.BasicCredentials(
-                    AUTH_HEADER.getHeader(), StandardCharsets.UTF_8, true);
+                    AUTH_HEADER.getHeader(), StandardCharsets.UTF_8);
         Assert.assertEquals(USER_NAME, credentials.getUsername());
-        Assert.assertEquals(PASSWORD, credentials.getPassword());
+        Assert.assertNotEquals(PASSWORD, credentials.getPassword());
+        Assert.assertEquals(PASSWORD, credentials.getPassword().trim());
     }
 
 
@@ -370,7 +338,7 @@ public class TestBasicAuthParser {
         @SuppressWarnings("unused") // Exception will be thrown.
         BasicAuthenticator.BasicCredentials credentials =
                 new BasicAuthenticator.BasicCredentials(
-                    AUTH_HEADER.getHeader(), StandardCharsets.UTF_8, true);
+                    AUTH_HEADER.getHeader(), StandardCharsets.UTF_8);
     }
 
     /*
@@ -386,44 +354,31 @@ public class TestBasicAuthParser {
         @SuppressWarnings("unused")
         BasicAuthenticator.BasicCredentials credentials =
                 new BasicAuthenticator.BasicCredentials(
-                    AUTH_HEADER.getHeader(), StandardCharsets.UTF_8, true);
+                    AUTH_HEADER.getHeader(), StandardCharsets.UTF_8);
     }
 
     /*
-     * "-" is not a legal base64 character. The RFC says it must be
-     * ignored by the decoder. This is a very strange case because the
-     * next character is a pad, which terminates the string normally.
-     * It is likely (but not certain) the decoded password will be
-     * damaged and subsequent authentication will fail.
+     * "-" is not a legal base64 character.
      */
-    @Test
+    @Test(expected=IllegalArgumentException.class)
     public void testBadBase64LastChar() throws Exception {
         final String BASE64_CRIB = "dXNlcmlkOnNlY3JldA-=";
-        final String POSSIBLY_DAMAGED_PWD = "secret";
-        final BasicAuthHeader AUTH_HEADER =
-                new BasicAuthHeader(NICE_METHOD, BASE64_CRIB);
+        final BasicAuthHeader AUTH_HEADER = new BasicAuthHeader(NICE_METHOD, 
BASE64_CRIB);
+        @SuppressWarnings("unused")
         BasicAuthenticator.BasicCredentials credentials =
-                new BasicAuthenticator.BasicCredentials(
-                    AUTH_HEADER.getHeader(), StandardCharsets.UTF_8, true);
-        Assert.assertEquals(USER_NAME, credentials.getUsername());
-        Assert.assertEquals(POSSIBLY_DAMAGED_PWD, credentials.getPassword());
+                new 
BasicAuthenticator.BasicCredentials(AUTH_HEADER.getHeader(), 
StandardCharsets.UTF_8);
     }
 
     /*
-     * The trailing third "=" is illegal. However, the RFC says the decoder
-     * must terminate as soon as the first pad is detected, so no error
-     * will be detected unless the payload has been damaged in some way.
+     * The trailing third "=" is illegal.
      */
-    @Test
+    @Test(expected=IllegalArgumentException.class)
     public void testBadBase64TooManyEquals() throws Exception {
         final String BASE64_CRIB = "dXNlcmlkOnNlY3JldA===";
-        final BasicAuthHeader AUTH_HEADER =
-                new BasicAuthHeader(NICE_METHOD, BASE64_CRIB);
+        final BasicAuthHeader AUTH_HEADER = new BasicAuthHeader(NICE_METHOD, 
BASE64_CRIB);
+        @SuppressWarnings("unused")
         BasicAuthenticator.BasicCredentials credentials =
-                new BasicAuthenticator.BasicCredentials(
-                    AUTH_HEADER.getHeader(), StandardCharsets.UTF_8, true);
-        Assert.assertEquals(USER_NAME, credentials.getUsername());
-        Assert.assertEquals(PASSWORD, credentials.getPassword());
+                new 
BasicAuthenticator.BasicCredentials(AUTH_HEADER.getHeader(), 
StandardCharsets.UTF_8);
     }
 
     /*
@@ -440,7 +395,7 @@ public class TestBasicAuthParser {
                 new BasicAuthHeader(NICE_METHOD, BASE64_CRIB);
         BasicAuthenticator.BasicCredentials credentials =
                 new BasicAuthenticator.BasicCredentials(
-                    AUTH_HEADER.getHeader(), StandardCharsets.UTF_8, true);
+                    AUTH_HEADER.getHeader(), StandardCharsets.UTF_8);
         Assert.assertEquals(USER_NAME, credentials.getUsername());
         Assert.assertEquals(PASSWORD, credentials.getPassword());
     }
@@ -479,7 +434,7 @@ public class TestBasicAuthParser {
                     : username + ":" + password;
             byte[] credentialsBytes =
                     userCredentials.getBytes(StandardCharsets.ISO_8859_1);
-            String base64auth = Base64.encodeBase64String(credentialsBytes);
+            String base64auth = 
Base64.getEncoder().encodeToString(credentialsBytes);
             byte[] base64Bytes =
                     base64auth.getBytes(StandardCharsets.ISO_8859_1);
 
diff --git a/webapps/docs/changelog.xml b/webapps/docs/changelog.xml
index eb03e0624f..73dc64ce03 100644
--- a/webapps/docs/changelog.xml
+++ b/webapps/docs/changelog.xml
@@ -118,6 +118,11 @@
         <bug>68890</bug> Align output encoding of JSPs in the Manager webapp
         with the XML declarations in those same files. (schultz)
       </fix>
+      <fix>
+        Update Basic authentication to implement the requirements of RFC 7617
+        including the removal of the <code>trimCredentials</code> setting which
+        is now hard-coded to <code>false</code>. (markt)
+      </fix>
     </changelog>
   </subsection>
   <subsection name="Coyote">
diff --git a/webapps/docs/config/valve.xml b/webapps/docs/config/valve.xml
index 0be8bef9b4..ce63a66764 100644
--- a/webapps/docs/config/valve.xml
+++ b/webapps/docs/config/valve.xml
@@ -1559,12 +1559,6 @@
         If not specified, the default value is <code>false</code>.</p>
       </attribute>
 
-      <attribute name="trimCredentials" required="false">
-        <p>Controls whether leading and/or trailing whitespace is removed from
-        the parsed credentials. If not specified, the default value is
-        <code>true</code>.</p>
-      </attribute>
-
     </attributes>
 
   </subsection>


---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org
For additional commands, e-mail: dev-h...@tomcat.apache.org

Reply via email to