Repository: GoogleContainerTools/jib (Java)

Issue:
Jib authentification does not respect www-authenticate specification allowing Basic auth without specifying realm
**Environment**:

- *Jib version:* 3.3.2
- *Build tool:* Gradle
- *OS:* Macos Ventura 13.3.1

**Description of the issue**:
When trying to login to my self-hosted Docker registry, Jib fails with the following error:
```
Caused by: com.google.cloud.tools.jib.api.RegistryAuthenticationFailedException: Failed to authenticate with registry <my registry> because: 'Bearer' was not found in the 'WWW-Authenticate' header, tried to parse: Basic
```
Having a look to `com.google.cloud.tools.jib.registry.RegistryAuthenticator#fromAuthenticationMethod` I see that regexp used to determine authentification method has a space before the `.*`. 
```java
authenticationMethod.matches("^(?i)(basic) .*")
```
This makes jib to fail to select auth method given header `WWW-Authenticate: Basic`

**Expected behavior**:
According to https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/WWW-Authenticate#syntax it is allowed to use `WWW-Authenticate: Basic` without providing any realm/charset. Jib should allow that

**Steps to reproduce**:
Try to login to any registry responding with `WWW-Authenticate: Basic` header.



Discussion:
#4035 should fix it.



Patch:
diff --git a/jib-core/src/main/java/com/google/cloud/tools/jib/registry/RegistryAuthenticator.java b/jib-core/src/main/java/com/google/cloud/tools/jib/registry/RegistryAuthenticator.java
index 1b4acde65d..0fc0a219da 100644
--- a/jib-core/src/main/java/com/google/cloud/tools/jib/registry/RegistryAuthenticator.java
+++ b/jib-core/src/main/java/com/google/cloud/tools/jib/registry/RegistryAuthenticator.java
@@ -72,9 +72,9 @@ static Optional<RegistryAuthenticator> fromAuthenticationMethod(
       @Nullable String userAgent,
       FailoverHttpClient httpClient)
       throws RegistryAuthenticationFailedException {
-    // If the authentication method starts with 'basic ' (case insensitive), no registry
+    // If the authentication method starts with 'basic' (case insensitive), no registry
     // authentication is needed.
-    if (authenticationMethod.matches("^(?i)(basic) .*")) {
+    if (authenticationMethod.matches("^(?i)(basic).*")) {
       return Optional.empty();
     }
 


Test patch:
diff --git a/jib-core/src/test/java/com/google/cloud/tools/jib/registry/RegistryAuthenticatorTest.java b/jib-core/src/test/java/com/google/cloud/tools/jib/registry/RegistryAuthenticatorTest.java
index fad7c41fcf..0ce5be3dba 100644
--- a/jib-core/src/test/java/com/google/cloud/tools/jib/registry/RegistryAuthenticatorTest.java
+++ b/jib-core/src/test/java/com/google/cloud/tools/jib/registry/RegistryAuthenticatorTest.java
@@ -16,6 +16,9 @@
 
 package com.google.cloud.tools.jib.registry;
 
+import static com.google.common.truth.Truth.assertThat;
+import static com.google.common.truth.Truth8.assertThat;
+
 import com.google.cloud.tools.jib.api.Credential;
 import com.google.cloud.tools.jib.api.RegistryAuthenticationFailedException;
 import com.google.cloud.tools.jib.http.FailoverHttpClient;
@@ -83,10 +86,11 @@ public void testFromAuthenticationMethod_bearer()
                 "user-agent",
                 httpClient)
             .get();
-    Assert.assertEquals(
-        new URL("https://somerealm?service=someservice&scope=repository:someimage:scope"),
-        registryAuthenticator.getAuthenticationUrl(
-            null, Collections.singletonMap("someimage", "scope")));
+    assertThat(
+            registryAuthenticator.getAuthenticationUrl(
+                null, Collections.singletonMap("someimage", "scope")))
+        .isEqualTo(
+            new URL("https://somerealm?service=someservice&scope=repository:someimage:scope"));
 
     registryAuthenticator =
         RegistryAuthenticator.fromAuthenticationMethod(
@@ -95,10 +99,11 @@ public void testFromAuthenticationMethod_bearer()
                 "user-agent",
                 httpClient)
             .get();
-    Assert.assertEquals(
-        new URL("https://somerealm?service=someservice&scope=repository:someimage:scope"),
-        registryAuthenticator.getAuthenticationUrl(
-            null, Collections.singletonMap("someimage", "scope")));
+    assertThat(
+            registryAuthenticator.getAuthenticationUrl(
+                null, Collections.singletonMap("someimage", "scope")))
+        .isEqualTo(
+            new URL("https://somerealm?service=someservice&scope=repository:someimage:scope"));
   }
 
   @Test
@@ -155,29 +160,34 @@ public void istAuthenticationUrl_oauth2() throws MalformedURLException {
 
   @Test
   public void testFromAuthenticationMethod_basic() throws RegistryAuthenticationFailedException {
-    Assert.assertFalse(
-        RegistryAuthenticator.fromAuthenticationMethod(
+    assertThat(
+            RegistryAuthenticator.fromAuthenticationMethod(
+                "Basic", registryEndpointRequestProperties, "user-agent", httpClient))
+        .isEmpty();
+
+    assertThat(
+            RegistryAuthenticator.fromAuthenticationMethod(
                 "Basic realm=\"https://somerealm\",service=\"someservice\",scope=\"somescope\"",
                 registryEndpointRequestProperties,
                 "user-agent",
-                httpClient)
-            .isPresent());
+                httpClient))
+        .isEmpty();
 
-    Assert.assertFalse(
-        RegistryAuthenticator.fromAuthenticationMethod(
+    assertThat(
+            RegistryAuthenticator.fromAuthenticationMethod(
                 "BASIC realm=\"https://somerealm\",service=\"someservice\",scope=\"somescope\"",
                 registryEndpointRequestProperties,
                 "user-agent",
-                httpClient)
-            .isPresent());
+                httpClient))
+        .isEmpty();
 
-    Assert.assertFalse(
-        RegistryAuthenticator.fromAuthenticationMethod(
+    assertThat(
+            RegistryAuthenticator.fromAuthenticationMethod(
                 "bASIC realm=\"https://somerealm\",service=\"someservice\",scope=\"somescope\"",
                 registryEndpointRequestProperties,
                 "user-agent",
-                httpClient)
-            .isPresent());
+                httpClient))
+        .isEmpty();
   }
 
   @Test