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("");