You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tomee.apache.org by rz...@apache.org on 2026/09/07 17:50:50 UTC
(tomee) 19/34: make anonymous GET handling on basic auth http listeners configurable
This is an automated email from the ASF dual-hosted git repository.
rzo1 pushed a commit to branch tomee-10.x
in repository https://gitbox.apache.org/repos/asf/tomee.git
commit 2018a8222742d1805d689278fff21a2e29e753ce
Author: Markus Jung <ju...@apache.org>
AuthorDate: Sat Aug 29 09:30:51 2026 +0200
make anonymous GET handling on basic auth http listeners configurable
(cherry picked from commit 76da08aa4676310b7dc1b2dcf551b08a8fc0d5f4)
---
.../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("");