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

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


The following commit(s) were added to refs/heads/10.1.x by this push:
     new e2a0578de1 Update Basic authentication to RFC 7617
e2a0578de1 is described below

commit e2a0578de1b0f15a3de078f14a3004a09e17921a
Author: Mark Thomas <ma...@apache.org>
AuthorDate: Tue Apr 16 11:55:49 2024 +0100

    Update Basic authentication to RFC 7617
---
 .../catalina/authenticator/BasicAuthenticator.java |  47 +++++-
 .../authenticator/TestBasicAuthParser.java         | 173 ++++++++++-----------
 webapps/docs/changelog.xml                         |   7 +
 webapps/docs/config/valve.xml                      |   4 +-
 4 files changed, 130 insertions(+), 101 deletions(-)

diff --git a/java/org/apache/catalina/authenticator/BasicAuthenticator.java 
b/java/org/apache/catalina/authenticator/BasicAuthenticator.java
index dd8e3c751f..7060cca97c 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,7 @@ public class BasicAuthenticator extends AuthenticatorBase {
 
     private Charset charset = StandardCharsets.ISO_8859_1;
     private String charsetString = null;
-    private boolean trimCredentials = true;
+    private boolean trimCredentials = false;
 
 
     public String getCharset() {
@@ -64,11 +64,27 @@ public class BasicAuthenticator extends AuthenticatorBase {
     }
 
 
+    /**
+     * Obtain the current setting for the removal of whitespace around the 
decoded user name and password.
+     *
+     * @return {@code true} if white space will be removed around the decoded 
user name and password
+     *
+     * @deprecated Will be removed in Tomcat 11 onwards.
+     */
+    @Deprecated
     public boolean getTrimCredentials() {
         return trimCredentials;
     }
 
 
+    /**
+     * Configures trimming of whitespace around the decoded user name and 
password.
+     *
+     * @param trimCredentials {@code true} to remove white space around the 
decoded user name and password
+     *
+     * @deprecated Will be removed in Tomcat 11 onwards.
+     */
+    @Deprecated
     public void setTrimCredentials(boolean trimCredentials) {
         this.trimCredentials = trimCredentials;
     }
@@ -155,15 +171,29 @@ 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
+         *
+         * @throws IllegalArgumentException If the header does not conform to 
RFC 7617
+         */
+        public BasicCredentials(ByteChunk input, Charset charset) throws 
IllegalArgumentException {
+            this(input, charset, false);
+        }
+
+        /**
+         * 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
+         *
+         * @deprecated Will be removed in Tomcat 11 onwards
          */
+        @Deprecated
         public BasicCredentials(ByteChunk input, Charset charset, boolean 
trimCredentials)
                 throws IllegalArgumentException {
             authorization = input;
@@ -196,7 +226,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 +246,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) {
diff --git a/test/org/apache/catalina/authenticator/TestBasicAuthParser.java 
b/test/org/apache/catalina/authenticator/TestBasicAuthParser.java
index d1dfe31f0b..03d91ba250 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,41 +272,46 @@ 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, "    ");
+        @SuppressWarnings("unused")
+        BasicAuthenticator.BasicCredentials credentials =
+                new 
BasicAuthenticator.BasicCredentials(AUTH_HEADER.getHeader(), 
StandardCharsets.UTF_8);
+    }
+
+    /*
+     * Confirm the Basic parser does not tolerate excess white space around 
the username inside the base64 blob.
+     */
+    @Test
+    public void testUserExtraSpace() throws Exception {
         final BasicAuthHeader AUTH_HEADER =
-                new BasicAuthHeader(NICE_METHOD, USER_NAME, PASSWORD, "    ");
+                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 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 tolerates excess white space around the user 
name inside the base64 blob when
+     * trimCredentials is enabled.
      */
     @Test
-    public void testUserExtraSpace() throws Exception {
+    public void testUserExtraSpaceWithTrimCredentials() throws Exception {
         final BasicAuthHeader AUTH_HEADER =
                 new BasicAuthHeader(NICE_METHOD, " " + USER_NAME + " ", 
PASSWORD);
+        @SuppressWarnings("deprecation")
         BasicAuthenticator.BasicCredentials credentials =
                 new BasicAuthenticator.BasicCredentials(
                 AUTH_HEADER.getHeader(), StandardCharsets.UTF_8, true);
@@ -332,17 +320,29 @@ public class TestBasicAuthParser {
     }
 
     /*
-     * 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 {
         final BasicAuthHeader AUTH_HEADER =
                 new BasicAuthHeader(NICE_METHOD, USER_NAME, " " + PASSWORD + " 
");
+        BasicAuthenticator.BasicCredentials credentials =
+                new BasicAuthenticator.BasicCredentials(
+                    AUTH_HEADER.getHeader(), StandardCharsets.UTF_8);
+        Assert.assertEquals(USER_NAME, credentials.getUsername());
+        Assert.assertNotEquals(PASSWORD, credentials.getPassword());
+        Assert.assertEquals(PASSWORD, credentials.getPassword().trim());
+    }
+
+    /*
+     * Confirm the Basic parser tolerates excess white space around the 
password inside the base64 blob when
+     * trimCredentials is enabled.
+     */
+    @Test
+    public void testPasswordExtraSpaceWithTrimCredentials() throws Exception {
+        final BasicAuthHeader AUTH_HEADER =
+                new BasicAuthHeader(NICE_METHOD, USER_NAME, " " + PASSWORD + " 
");
+        @SuppressWarnings("deprecation")
         BasicAuthenticator.BasicCredentials credentials =
                 new BasicAuthenticator.BasicCredentials(
                     AUTH_HEADER.getHeader(), StandardCharsets.UTF_8, true);
@@ -370,7 +370,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 +386,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 +427,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 +466,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 9b7db56706..89bd49ddc8 100644
--- a/webapps/docs/changelog.xml
+++ b/webapps/docs/changelog.xml
@@ -118,6 +118,13 @@
         <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 changing of the <code>trimCredentials</code> setting 
which
+        is now defaults to <code>false</code>. Note that the
+        <code>trimCredentials</code> setting will be removed in Tomcat 11.
+        (markt)
+      </fix>
     </changelog>
   </subsection>
   <subsection name="Coyote">
diff --git a/webapps/docs/config/valve.xml b/webapps/docs/config/valve.xml
index 7f859cc2cd..ceb4a84218 100644
--- a/webapps/docs/config/valve.xml
+++ b/webapps/docs/config/valve.xml
@@ -1562,7 +1562,9 @@
       <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>
+        <code>false</code>.
+        </p>
+        <p>Note: This attribute will be removed from Tomcat 11 onwards.</p>
       </attribute>
 
     </attributes>


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

Reply via email to