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

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


The following commit(s) were added to refs/heads/main by this push:
     new 76da08aa46 make anonymous GET handling on basic auth http listeners 
configurable
76da08aa46 is described below

commit 76da08aa4676310b7dc1b2dcf551b08a8fc0d5f4
Author: Markus Jung <[email protected]>
AuthorDate: Sat Aug 29 09:30:51 2026 +0200

    make anonymous GET handling on basic auth http listeners configurable
---
 .../server/httpd/BasicAuthHttpListenerWrapper.java | 19 +++++-
 .../httpd/BasicAuthHttpListenerWrapperTest.java    | 71 ++++++++++++++++++++++
 .../server/webservices/OpenEJBHttpWsRegistry.java  |  2 +-
 3 files changed, 88 insertions(+), 4 deletions(-)

diff --git 
a/server/openejb-http/src/main/java/org/apache/openejb/server/httpd/BasicAuthHttpListenerWrapper.java
 
b/server/openejb-http/src/main/java/org/apache/openejb/server/httpd/BasicAuthHttpListenerWrapper.java
index f9c32d5762..673e00e79a 100644
--- 
a/server/openejb-http/src/main/java/org/apache/openejb/server/httpd/BasicAuthHttpListenerWrapper.java
+++ 
b/server/openejb-http/src/main/java/org/apache/openejb/server/httpd/BasicAuthHttpListenerWrapper.java
@@ -21,6 +21,8 @@ import org.apache.openejb.loader.SystemInstance;
 import org.apache.openejb.spi.SecurityService;
 import org.apache.openejb.util.Base64;
 
+import jakarta.servlet.http.HttpServletResponse;
+
 import javax.security.auth.login.LoginException;
 import java.util.Locale;
 
@@ -28,10 +30,20 @@ public class BasicAuthHttpListenerWrapper implements 
HttpListener {
 
     private final HttpListener httpListener;
     private final String realmName;
+    private final boolean anonymousGet;
 
     public BasicAuthHttpListenerWrapper(final HttpListener httpListener, final 
String realmName) {
+        this(httpListener, realmName, false);
+    }
+
+    /**
+     * @param anonymousGet when true, GET requests are dispatched without 
credentials
+     *                     (used for wsdl/xsd retrieval on webservice 
endpoints)
+     */
+    public BasicAuthHttpListenerWrapper(final HttpListener httpListener, final 
String realmName, final boolean anonymousGet) {
         this.httpListener = httpListener;
         this.realmName = realmName;
+        this.anonymousGet = anonymousGet;
     }
 
     @Override
@@ -44,7 +56,7 @@ public class BasicAuthHttpListenerWrapper implements 
HttpListener {
             if (auth.toUpperCase(Locale.ENGLISH).startsWith("BASIC ")) {
                 auth = auth.substring(6);
                 final String decoded = new 
String(Base64.decodeBase64(auth.getBytes()));
-                final String[] parts = decoded.split(":");
+                final String[] parts = decoded.split(":", 2);
                 if (parts.length == 2) {
                     final String username = parts[0];
                     final String password = parts[1];
@@ -63,10 +75,11 @@ public class BasicAuthHttpListenerWrapper implements 
HttpListener {
         }
 
         try {
-            if (token != null || 
HttpRequest.Method.GET.name().equals(request.getMethod())) {
+            if (token != null || (anonymousGet && 
HttpRequest.Method.GET.name().equals(request.getMethod()))) {
                 httpListener.onMessage(request, response);
             } else {
-                // login failed,  return 401
+                response.setHeader("WWW-Authenticate", "Basic realm=\"" + 
(realmName == null ? "" : realmName) + "\"");
+                response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
             }
         } finally {
             if (token != null) {
diff --git 
a/server/openejb-http/src/test/java/org/apache/openejb/server/httpd/BasicAuthHttpListenerWrapperTest.java
 
b/server/openejb-http/src/test/java/org/apache/openejb/server/httpd/BasicAuthHttpListenerWrapperTest.java
new file mode 100644
index 0000000000..47ccdfb469
--- /dev/null
+++ 
b/server/openejb-http/src/test/java/org/apache/openejb/server/httpd/BasicAuthHttpListenerWrapperTest.java
@@ -0,0 +1,71 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.openejb.server.httpd;
+
+import org.junit.Test;
+
+import java.io.ByteArrayInputStream;
+import java.net.URI;
+import java.nio.charset.StandardCharsets;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+public class BasicAuthHttpListenerWrapperTest {
+    @Test
+    public void getWithoutCredentialsIsChallenged() throws Exception {
+        final AtomicBoolean dispatched = new AtomicBoolean(false);
+        final BasicAuthHttpListenerWrapper wrapper = new 
BasicAuthHttpListenerWrapper(listener(dispatched), "TestRealm");
+        final HttpResponseImpl response = new HttpResponseImpl();
+
+        wrapper.onMessage(get(), response);
+
+        assertFalse(dispatched.get());
+        assertEquals(401, response.getStatus());
+        assertEquals("Basic realm=\"TestRealm\"", 
response.getHeader("WWW-Authenticate"));
+    }
+
+    @Test
+    public void anonymousGetIsDispatchedWhenEnabled() throws Exception {
+        final AtomicBoolean dispatched = new AtomicBoolean(false);
+        final BasicAuthHttpListenerWrapper wrapper = new 
BasicAuthHttpListenerWrapper(listener(dispatched), "TestRealm", true);
+        final HttpResponseImpl response = new HttpResponseImpl();
+
+        wrapper.onMessage(get(), response);
+
+        assertTrue(dispatched.get());
+        assertEquals(200, response.getStatus());
+    }
+
+    private static HttpListener listener(final AtomicBoolean dispatched) {
+        return new HttpListener() {
+            @Override
+            public void onMessage(final HttpRequest request, final 
HttpResponse response) {
+                dispatched.set(true);
+            }
+        };
+    }
+
+    private static HttpRequestImpl get() throws Exception {
+        final HttpRequestImpl request = new HttpRequestImpl(new 
URI("http://localhost:4204";));
+        assertTrue(request.readMessage(new ByteArrayInputStream(
+                "GET /app/api/customers 
HTTP/1.1\r\n\r\n".getBytes(StandardCharsets.ISO_8859_1))));
+        return request;
+    }
+}
diff --git 
a/server/openejb-webservices/src/main/java/org/apache/openejb/server/webservices/OpenEJBHttpWsRegistry.java
 
b/server/openejb-webservices/src/main/java/org/apache/openejb/server/webservices/OpenEJBHttpWsRegistry.java
index bfd0abdfa7..39e2bf54d3 100644
--- 
a/server/openejb-webservices/src/main/java/org/apache/openejb/server/webservices/OpenEJBHttpWsRegistry.java
+++ 
b/server/openejb-webservices/src/main/java/org/apache/openejb/server/webservices/OpenEJBHttpWsRegistry.java
@@ -59,7 +59,7 @@ public class OpenEJBHttpWsRegistry extends 
OpenEJBHttpRegistry implements WsRegi
         if (httpListener == null) throw new NullPointerException("httpListener 
is null");
 
         if ("BASIC".equals(authMethod)) {
-            httpListener = new BasicAuthHttpListenerWrapper(httpListener, 
realmName);
+            httpListener = new BasicAuthHttpListenerWrapper(httpListener, 
realmName, true);
         }
 
         final StringBuilder deployedPath = new StringBuilder("");

Reply via email to