You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cxf.apache.org by re...@apache.org on 2023/05/21 15:50:52 UTC
[cxf] 01/02: CXF-8882: Apache HttpClient 5 async conduit does not handle authentication (#1279)
This is an automated email from the ASF dual-hosted git repository.
reta pushed a commit to branch 3.6.x-fixes
in repository https://gitbox.apache.org/repos/asf/cxf.git
commit 6d68137820399873504ea5d7edeee12b0c17aaec
Author: Andriy Redko <dr...@gmail.com>
AuthorDate: Sun May 21 09:38:31 2023 -0400
CXF-8882: Apache HttpClient 5 async conduit does not handle authentication (#1279)
(cherry picked from commit 153ecb7c32332882843333856ec4323e75d3f0fc)
# Conflicts:
# systests/transport-hc5/pom.xml
# systests/transport-hc5/src/test/java/org/apache/cxf/systest/hc5/http/auth/DigestAuthSupplierSpringTest.java
---
.../http/asyncclient/hc5/AsyncHTTPConduit.java | 2 +-
.../hc5/CXFHttpAsyncRequestProducer.java | 36 +----
systests/transport-hc5/pom.xml | 37 ++++-
.../http/auth/DigestAuthSupplierSpringTest.java | 152 +++++++++++++++++++
.../cxf/systest/hc5/http/auth/DigestAuthTest.java | 158 ++++++++++++++++++++
.../cxf/systest/hc5/http/auth/DigestServer.java | 81 ++++++++++
.../cxf/systest/hc5/http/auth/GreeterImpl.java | 20 ++-
.../systest/hc5/http/auth/jetty-realm.properties | 2 +
.../test/resources/digestauth/WEB-INF/beans.xml | 36 +++++
.../src/test/resources/digestauth/WEB-INF/web.xml | 47 ++++++
.../src/test/resources/logging.properties | 74 +++++++++
.../org/apache/cxf/systest/hc5/http/greeting.wsdl | 166 +++++++++++++++++++++
12 files changed, 769 insertions(+), 42 deletions(-)
diff --git a/rt/transports/http-hc5/src/main/java/org/apache/cxf/transport/http/asyncclient/hc5/AsyncHTTPConduit.java b/rt/transports/http-hc5/src/main/java/org/apache/cxf/transport/http/asyncclient/hc5/AsyncHTTPConduit.java
index 5093597495..e888cfd27b 100644
--- a/rt/transports/http-hc5/src/main/java/org/apache/cxf/transport/http/asyncclient/hc5/AsyncHTTPConduit.java
+++ b/rt/transports/http-hc5/src/main/java/org/apache/cxf/transport/http/asyncclient/hc5/AsyncHTTPConduit.java
@@ -606,7 +606,7 @@ public class AsyncHTTPConduit extends HttpClientHTTPConduit {
final HttpAsyncClient c = getHttpAsyncClient(tlsStrategy);
final Credentials creds = (Credentials)outMessage.getContextualProperty(Credentials.class.getName());
if (creds != null) {
- credsProvider.setCredentials(new AnyAuthScope(), creds);
+ credsProvider.setCredentials(new AuthScope(url.getHost(), url.getPort()), creds);
ctx.setUserToken(creds.getUserPrincipal());
}
@SuppressWarnings("unchecked")
diff --git a/rt/transports/http-hc5/src/main/java/org/apache/cxf/transport/http/asyncclient/hc5/CXFHttpAsyncRequestProducer.java b/rt/transports/http-hc5/src/main/java/org/apache/cxf/transport/http/asyncclient/hc5/CXFHttpAsyncRequestProducer.java
index a3e0862902..896dcfd68c 100644
--- a/rt/transports/http-hc5/src/main/java/org/apache/cxf/transport/http/asyncclient/hc5/CXFHttpAsyncRequestProducer.java
+++ b/rt/transports/http-hc5/src/main/java/org/apache/cxf/transport/http/asyncclient/hc5/CXFHttpAsyncRequestProducer.java
@@ -22,7 +22,6 @@ package org.apache.cxf.transport.http.asyncclient.hc5;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
-import java.net.URI;
import java.nio.Buffer;
import java.nio.ByteBuffer;
import java.nio.channels.Channels;
@@ -30,8 +29,6 @@ import java.nio.channels.ReadableByteChannel;
import org.apache.cxf.io.CachedOutputStream;
import org.apache.hc.core5.http.HttpException;
-import org.apache.hc.core5.http.HttpHost;
-import org.apache.hc.core5.http.HttpRequest;
import org.apache.hc.core5.http.nio.AsyncRequestProducer;
import org.apache.hc.core5.http.nio.DataStreamChannel;
import org.apache.hc.core5.http.nio.RequestChannel;
@@ -51,21 +48,6 @@ public class CXFHttpAsyncRequestProducer implements AsyncRequestProducer {
this.request = request;
}
- public HttpHost getTarget() {
- URI uri = request.getUri();
- if (uri == null) {
- throw new IllegalStateException("Request URI is null");
- }
- if (!uri.isAbsolute()) {
- throw new IllegalStateException("Request URI is not absolute");
- }
- return new HttpHost(uri.getScheme(), uri.getHost(), uri.getPort());
- }
-
- public HttpRequest generateRequest() throws IOException, HttpException {
- return request;
- }
-
@Override
public void produce(DataStreamChannel channel) throws IOException {
if (content != null) {
@@ -94,28 +76,17 @@ public class CXFHttpAsyncRequestProducer implements AsyncRequestProducer {
}
}
- public void requestCompleted(final HttpContext context) {
- if (fis != null) {
- try {
- fis.close();
- } catch (IOException io) {
- //ignore
- }
- chan = null;
- fis = null;
- }
- buffer = null;
- }
-
+ @Override
public void failed(final Exception ex) {
buf.shutdown();
}
+ @Override
public boolean isRepeatable() {
return request.getOutputStream().retransmitable();
}
- public void resetRequest() throws IOException {
+ private void resetRequest() {
if (request.getOutputStream().retransmitable()) {
content = request.getOutputStream().getCachedStream();
}
@@ -139,6 +110,7 @@ public class CXFHttpAsyncRequestProducer implements AsyncRequestProducer {
fis = null;
}
buffer = null;
+ resetRequest();
}
@Override
diff --git a/systests/transport-hc5/pom.xml b/systests/transport-hc5/pom.xml
index bd7c140ab6..442fbe8863 100644
--- a/systests/transport-hc5/pom.xml
+++ b/systests/transport-hc5/pom.xml
@@ -107,10 +107,14 @@
<artifactId>jetty-alpn-server</artifactId>
<scope>test</scope>
</dependency>
+ <dependency>
+ <groupId>org.eclipse.jetty</groupId>
+ <artifactId>jetty-webapp</artifactId>
+ <scope>test</scope>
+ </dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-alpn-java-server</artifactId>
- <version>${cxf.jetty10.version}</version>
<scope>test</scope>
</dependency>
<dependency>
@@ -185,5 +189,36 @@
<artifactId>spring-context</artifactId>
<scope>test</scope>
</dependency>
+ <dependency>
+ <groupId>org.springframework.security</groupId>
+ <artifactId>spring-security-config</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.springframework.security</groupId>
+ <artifactId>spring-security-web</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.springframework.boot</groupId>
+ <artifactId>spring-boot-starter-test</artifactId>
+ <version>${cxf.spring.boot.version}</version>
+ <scope>test</scope>
+ <exclusions>
+ <exclusion>
+ <groupId>org.springframework.boot</groupId>
+ <artifactId>spring-boot-starter-logging</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>org.junit.jupiter</groupId>
+ <artifactId>junit-jupiter</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+ <dependency>
+ <groupId>org.springframework.boot</groupId>
+ <artifactId>spring-boot-starter-web</artifactId>
+ <scope>test</scope>
+ </dependency>
</dependencies>
</project>
diff --git a/systests/transport-hc5/src/test/java/org/apache/cxf/systest/hc5/http/auth/DigestAuthSupplierSpringTest.java b/systests/transport-hc5/src/test/java/org/apache/cxf/systest/hc5/http/auth/DigestAuthSupplierSpringTest.java
new file mode 100644
index 0000000000..6a71ddae8e
--- /dev/null
+++ b/systests/transport-hc5/src/test/java/org/apache/cxf/systest/hc5/http/auth/DigestAuthSupplierSpringTest.java
@@ -0,0 +1,152 @@
+/**
+ * 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.cxf.systest.hc5.http.auth;
+
+import javax.ws.rs.NotAuthorizedException;
+import javax.ws.rs.core.MediaType;
+import org.apache.cxf.jaxrs.client.WebClient;
+import org.apache.cxf.transport.http.HTTPConduit;
+import org.apache.cxf.transport.http.auth.DigestAuthSupplier;
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
+import org.springframework.boot.test.web.server.LocalServerPort;
+import org.springframework.context.annotation.Bean;
+import org.springframework.security.config.annotation.web.builders.HttpSecurity;
+import org.springframework.security.core.userdetails.User;
+import org.springframework.security.core.userdetails.UserDetails;
+import org.springframework.security.crypto.password.PasswordEncoder;
+import org.springframework.security.provisioning.InMemoryUserDetailsManager;
+import org.springframework.security.web.SecurityFilterChain;
+import org.springframework.security.web.authentication.www.DigestAuthenticationEntryPoint;
+import org.springframework.security.web.authentication.www.DigestAuthenticationFilter;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+
+@RunWith(SpringJUnit4ClassRunner.class)
+@SpringBootTest(
+ classes = {
+ DigestAuthSupplierSpringTest.SecurityConfig.class,
+ DigestAuthSupplierSpringTest.Controller.class
+ },
+ webEnvironment = WebEnvironment.RANDOM_PORT
+)
+@SpringBootApplication
+public class DigestAuthSupplierSpringTest {
+
+ private static final String USER = "alice";
+ private static final String PWD = "ecila";
+
+ @LocalServerPort
+ private int port;
+
+ @Test
+ public void test() {
+ WebClient client = WebClient.create("http://localhost:" + port, (String) null);
+
+ assertThrows(NotAuthorizedException.class, () -> client.get(String.class));
+
+ HTTPConduit conduit = WebClient.getConfig(client).getHttpConduit();
+ conduit.setAuthSupplier(new DigestAuthSupplier());
+ conduit.getAuthorization().setUserName(USER);
+ conduit.getAuthorization().setPassword(PWD);
+
+ assertEquals(Controller.RESPONSE, client.get(String.class));
+ }
+
+ @RestController
+ static class Controller {
+
+ static final String RESPONSE = "Hi!";
+
+ @GetMapping(produces = MediaType.TEXT_PLAIN, value = "/")
+ public String get() {
+ return "Hi!";
+ }
+
+ }
+
+ static class SecurityConfig {
+
+ @Bean
+ public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
+ DigestAuthenticationEntryPoint authenticationEntryPoint = digestAuthenticationEntryPoint();
+ return http
+ .authorizeRequests().anyRequest().authenticated()
+ .and()
+ .exceptionHandling().authenticationEntryPoint(authenticationEntryPoint)
+ .and()
+ .addFilter(digestAuthenticationFilter(authenticationEntryPoint))
+ .build();
+ }
+
+ private DigestAuthenticationFilter digestAuthenticationFilter(
+ DigestAuthenticationEntryPoint authenticationEntryPoint) {
+ DigestAuthenticationFilter digestAuthenticationFilter = new DigestAuthenticationFilter();
+ digestAuthenticationFilter.setUserDetailsService(userDetailsService());
+ digestAuthenticationFilter.setAuthenticationEntryPoint(authenticationEntryPoint);
+ return digestAuthenticationFilter;
+ }
+
+ private static DigestAuthenticationEntryPoint digestAuthenticationEntryPoint() {
+ DigestAuthenticationEntryPoint digestAuthenticationEntryPoint = new DigestAuthenticationEntryPoint();
+ digestAuthenticationEntryPoint.setKey("acegi");
+ digestAuthenticationEntryPoint.setRealmName("Digest Realm");
+ return digestAuthenticationEntryPoint;
+ }
+
+ @Bean
+ public InMemoryUserDetailsManager userDetailsService() {
+ final UserDetails user = User
+ .builder()
+ .username(USER)
+ .password(PWD)
+ .roles("")
+ .build();
+ return new InMemoryUserDetailsManager(user);
+ }
+
+ @Bean
+ public static PasswordEncoder passwordEncoder() {
+ return new PasswordEncoder() {
+ @Override
+ public String encode(CharSequence rawPassword) {
+ return rawPassword.toString();
+ }
+ @Override
+ public boolean matches(CharSequence rawPassword, String encodedPassword) {
+ return rawPassword.toString().equals(encodedPassword);
+ }
+ };
+ }
+ }
+
+ public static void main(String[] args) {
+ SpringApplication.run(DigestAuthSupplierSpringTest.class, args);
+ }
+
+}
diff --git a/systests/transport-hc5/src/test/java/org/apache/cxf/systest/hc5/http/auth/DigestAuthTest.java b/systests/transport-hc5/src/test/java/org/apache/cxf/systest/hc5/http/auth/DigestAuthTest.java
new file mode 100644
index 0000000000..050f3e7c60
--- /dev/null
+++ b/systests/transport-hc5/src/test/java/org/apache/cxf/systest/hc5/http/auth/DigestAuthTest.java
@@ -0,0 +1,158 @@
+/**
+ * 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.cxf.systest.hc5.http.auth;
+
+
+import java.net.URL;
+import java.util.Map;
+
+import javax.xml.namespace.QName;
+import javax.xml.ws.BindingProvider;
+
+import org.apache.cxf.ext.logging.LoggingInInterceptor;
+import org.apache.cxf.ext.logging.LoggingOutInterceptor;
+import org.apache.cxf.frontend.ClientProxy;
+import org.apache.cxf.helpers.CastUtils;
+import org.apache.cxf.interceptor.Fault;
+import org.apache.cxf.message.Message;
+import org.apache.cxf.phase.AbstractPhaseInterceptor;
+import org.apache.cxf.phase.Phase;
+import org.apache.cxf.testutil.common.AbstractBusClientServerTestBase;
+import org.apache.cxf.testutil.common.TestUtil;
+import org.apache.cxf.transport.http.HTTPConduit;
+import org.apache.cxf.transport.http.HTTPException;
+import org.apache.cxf.transport.http.asyncclient.hc5.AsyncHTTPConduit;
+import org.apache.cxf.transport.http.auth.DigestAuthSupplier;
+import org.apache.cxf.transports.http.configuration.HTTPClientPolicy;
+import org.apache.hc.client5.http.auth.Credentials;
+import org.apache.hc.client5.http.auth.UsernamePasswordCredentials;
+import org.apache.hello_world.Greeter;
+import org.apache.hello_world.services.SOAPService;
+
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.fail;
+
+
+public class DigestAuthTest extends AbstractBusClientServerTestBase {
+ public static final String PORT = allocatePort(DigestServer.class);
+
+ private final QName serviceName =
+ new QName("http://apache.org/hello_world", "SOAPService");
+ private final QName mortimerQ =
+ new QName("http://apache.org/hello_world", "Mortimer");
+
+ @BeforeClass
+ public static void startServer() throws Exception {
+ launchServer(DigestServer.class, true);
+ createStaticBus();
+ }
+
+ @Test
+ public void testDigestAuth() throws Exception {
+ final Greeter mortimer = setupClient(false);
+ final String answer = mortimer.sayHi();
+ assertEquals("Unexpected answer: " + answer, "Hi", answer);
+ }
+
+ @Test
+ public void testDigestAuthAsync() throws Exception {
+ final Greeter mortimer = setupClient(true);
+ final String answer = mortimer.sayHi();
+ assertEquals("Unexpected answer: " + answer, "Hi", answer);
+ }
+
+ @Test
+ public void testNoAuth() throws Exception {
+ URL wsdl = getClass().getResource("../greeting.wsdl");
+ assertNotNull("WSDL is null", wsdl);
+
+ SOAPService service = new SOAPService(wsdl, serviceName);
+ assertNotNull("Service is null", service);
+
+ Greeter mortimer = service.getPort(mortimerQ, Greeter.class);
+ assertNotNull("Port is null", mortimer);
+
+ TestUtil.setAddress(mortimer, "http://localhost:" + PORT + "/digestauth/greeter");
+
+ try {
+ String answer = mortimer.sayHi();
+ fail("Unexpected reply (" + answer + "). Should throw exception");
+ } catch (Exception e) {
+ Throwable cause = e.getCause();
+ assertEquals(HTTPException.class, cause.getClass());
+ HTTPException he = (HTTPException)cause;
+ assertEquals(401, he.getResponseCode());
+ }
+ }
+
+ private Greeter setupClient(boolean async) throws Exception {
+ URL wsdl = getClass().getResource("../greeting.wsdl");
+ assertNotNull("WSDL is null", wsdl);
+
+ SOAPService service = new SOAPService(wsdl, serviceName);
+ assertNotNull("Service is null", service);
+
+ Greeter mortimer = service.getPort(mortimerQ, Greeter.class);
+ assertNotNull("Port is null", mortimer);
+
+ BindingProvider bp = (BindingProvider)mortimer;
+ ClientProxy.getClient(mortimer).getInInterceptors().add(new LoggingInInterceptor());
+ ClientProxy.getClient(mortimer).getOutInterceptors().add(new LoggingOutInterceptor());
+ bp.getRequestContext().put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY,
+ "http://localhost:" + PORT + "/digestauth/greeter");
+ HTTPConduit cond = (HTTPConduit)ClientProxy.getClient(mortimer).getConduit();
+ HTTPClientPolicy client = new HTTPClientPolicy();
+ client.setConnectionTimeout(600000);
+ client.setReceiveTimeout(600000);
+ cond.setClient(client);
+ if (async) {
+ if (cond instanceof AsyncHTTPConduit) {
+ UsernamePasswordCredentials creds = new UsernamePasswordCredentials("foo", "bar".toCharArray());
+ bp.getRequestContext().put(Credentials.class.getName(), creds);
+ bp.getRequestContext().put(AsyncHTTPConduit.USE_ASYNC, Boolean.TRUE);
+ client.setAutoRedirect(true);
+ } else {
+ fail("Not an async conduit");
+ }
+ } else {
+ bp.getRequestContext().put(BindingProvider.USERNAME_PROPERTY, "foo");
+ bp.getRequestContext().put(BindingProvider.PASSWORD_PROPERTY, "bar");
+ cond.setAuthSupplier(new DigestAuthSupplier());
+ }
+
+ ClientProxy.getClient(mortimer).getOutInterceptors()
+ .add(new AbstractPhaseInterceptor<Message>(Phase.PRE_STREAM_ENDING) {
+
+ public void handleMessage(Message message) throws Fault {
+ Map<String, ?> headers = CastUtils.cast((Map<?, ?>)message.get(Message.PROTOCOL_HEADERS));
+ if (headers.containsKey("Proxy-Authorization")) {
+ throw new RuntimeException("Should not have Proxy-Authorization");
+ }
+ }
+ });
+ client.setAllowChunking(false);
+ return mortimer;
+ }
+}
+
diff --git a/systests/transport-hc5/src/test/java/org/apache/cxf/systest/hc5/http/auth/DigestServer.java b/systests/transport-hc5/src/test/java/org/apache/cxf/systest/hc5/http/auth/DigestServer.java
new file mode 100644
index 0000000000..dd0c5cef9c
--- /dev/null
+++ b/systests/transport-hc5/src/test/java/org/apache/cxf/systest/hc5/http/auth/DigestServer.java
@@ -0,0 +1,81 @@
+/**
+ * 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.cxf.systest.hc5.http.auth;
+
+import java.net.URL;
+
+import org.apache.cxf.testutil.common.AbstractBusTestServerBase;
+import org.eclipse.jetty.security.HashLoginService;
+import org.eclipse.jetty.security.LoginService;
+import org.eclipse.jetty.server.Handler;
+import org.eclipse.jetty.server.handler.DefaultHandler;
+import org.eclipse.jetty.server.handler.HandlerCollection;
+import org.eclipse.jetty.util.resource.Resource;
+import org.eclipse.jetty.webapp.WebAppContext;
+
+public class DigestServer extends AbstractBusTestServerBase {
+ public static final String PORT = allocatePort(DigestServer.class);
+
+ private org.eclipse.jetty.server.Server server;
+
+ private void configureServer() throws Exception {
+ URL resource = getClass().getResource("jetty-realm.properties");
+
+ LoginService realm =
+ new HashLoginService("BookStoreRealm", resource.toString());
+ server.addBean(realm);
+ }
+
+ protected void run() {
+ server = new org.eclipse.jetty.server.Server(Integer.parseInt(PORT));
+
+ WebAppContext webappcontext = new WebAppContext();
+ webappcontext.setContextPath("/digestauth");
+ webappcontext.setBaseResource(Resource.newClassPathResource("/digestauth"));
+
+ HandlerCollection handlers = new HandlerCollection();
+ handlers.setHandlers(new Handler[] {webappcontext, new DefaultHandler()});
+
+ server.setHandler(handlers);
+
+ try {
+ configureServer();
+ server.start();
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+ public void tearDown() throws Exception {
+ if (server != null) {
+ server.stop();
+ server.destroy();
+ server = null;
+ }
+ }
+ public static void main(String[] args) {
+ try {
+ DigestServer s = new DigestServer();
+ s.start();
+ } catch (Exception ex) {
+ ex.printStackTrace();
+ System.exit(-1);
+ }
+ }
+
+}
diff --git a/rt/transports/http-hc5/src/main/java/org/apache/cxf/transport/http/asyncclient/hc5/AnyAuthScope.java b/systests/transport-hc5/src/test/java/org/apache/cxf/systest/hc5/http/auth/GreeterImpl.java
similarity index 69%
rename from rt/transports/http-hc5/src/main/java/org/apache/cxf/transport/http/asyncclient/hc5/AnyAuthScope.java
rename to systests/transport-hc5/src/test/java/org/apache/cxf/systest/hc5/http/auth/GreeterImpl.java
index c79815fe70..ff92540a45 100644
--- a/rt/transports/http-hc5/src/main/java/org/apache/cxf/transport/http/asyncclient/hc5/AnyAuthScope.java
+++ b/systests/transport-hc5/src/test/java/org/apache/cxf/systest/hc5/http/auth/GreeterImpl.java
@@ -16,18 +16,22 @@
* specific language governing permissions and limitations
* under the License.
*/
+package org.apache.cxf.systest.hc5.http.auth;
-package org.apache.cxf.transport.http.asyncclient.hc5;
+import org.apache.hello_world.Greeter;
+import org.apache.hello_world.messages.PingMeFault;
-import org.apache.hc.client5.http.auth.AuthScope;
+public class GreeterImpl implements Greeter {
-class AnyAuthScope extends AuthScope {
- AnyAuthScope() {
- super(null, null, 1, null, null);
+ public String sayHi() {
+ return "Hi";
}
- @Override
- public int match(AuthScope that) {
- return 1;
+ public void pingMe() throws PingMeFault {
}
+
+ public String greetMe(String requestType) {
+ return null;
+ }
+
}
diff --git a/systests/transport-hc5/src/test/java/org/apache/cxf/systest/hc5/http/auth/jetty-realm.properties b/systests/transport-hc5/src/test/java/org/apache/cxf/systest/hc5/http/auth/jetty-realm.properties
new file mode 100644
index 0000000000..0d950fbd8f
--- /dev/null
+++ b/systests/transport-hc5/src/test/java/org/apache/cxf/systest/hc5/http/auth/jetty-realm.properties
@@ -0,0 +1,2 @@
+foo: bar,ROLE_USER
+
diff --git a/systests/transport-hc5/src/test/resources/digestauth/WEB-INF/beans.xml b/systests/transport-hc5/src/test/resources/digestauth/WEB-INF/beans.xml
new file mode 100644
index 0000000000..670c00064f
--- /dev/null
+++ b/systests/transport-hc5/src/test/resources/digestauth/WEB-INF/beans.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ 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.
+-->
+<beans xmlns="http://www.springframework.org/schema/beans"
+ xmlns:http="http://cxf.apache.org/transports/http/configuration"
+ xmlns:jaxws="http://cxf.apache.org/jaxws"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="
+ http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
+ http://cxf.apache.org/transports/http/configuration http://cxf.apache.org/schemas/configuration/http-conf.xsd
+ http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd
+ ">
+ <import resource="classpath:META-INF/cxf/cxf.xml"/>
+ <import resource="classpath:META-INF/cxf/cxf-servlet.xml"/>
+ <http:destination name="{http://apache.org/hello_world}Mortimer.http-destination">
+ <!-- Nothing to Configure here for Mortimer -->
+ </http:destination>
+ <bean id="greeterImpl" class="org.apache.cxf.systest.hc5.http.auth.GreeterImpl" />
+ <jaxws:endpoint address="/greeter" implementor="#greeterImpl" publish="true"/>
+</beans>
diff --git a/systests/transport-hc5/src/test/resources/digestauth/WEB-INF/web.xml b/systests/transport-hc5/src/test/resources/digestauth/WEB-INF/web.xml
new file mode 100644
index 0000000000..5f3e2fe065
--- /dev/null
+++ b/systests/transport-hc5/src/test/resources/digestauth/WEB-INF/web.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<!-- 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. -->
+<web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
+ version="3.0">
+ <context-param>
+ <param-name>contextConfigLocation</param-name>
+ <param-value>WEB-INF/beans.xml</param-value>
+ </context-param>
+ <listener>
+ <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
+ </listener>
+ <servlet>
+ <servlet-name>CXFServlet</servlet-name>
+ <servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class>
+ <load-on-startup>1</load-on-startup>
+ </servlet>
+ <servlet-mapping>
+ <servlet-name>CXFServlet</servlet-name>
+ <url-pattern>/*</url-pattern>
+ </servlet-mapping>
+ <security-constraint>
+ <web-resource-collection>
+ <web-resource-name>CXFServlet</web-resource-name>
+ <url-pattern>/*</url-pattern>
+ </web-resource-collection>
+ <auth-constraint>
+ <role-name>ROLE_USER</role-name>
+ </auth-constraint>
+ </security-constraint>
+ <login-config>
+ <auth-method>DIGEST</auth-method>
+ <realm-name>BookStoreRealm</realm-name>
+ </login-config>
+ <security-role>
+ <role-name>ROLE_USER</role-name>
+ </security-role>
+</web-app>
diff --git a/systests/transport-hc5/src/test/resources/logging.properties b/systests/transport-hc5/src/test/resources/logging.properties
new file mode 100644
index 0000000000..b2e5a799c8
--- /dev/null
+++ b/systests/transport-hc5/src/test/resources/logging.properties
@@ -0,0 +1,74 @@
+#
+#
+# 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.
+#
+#
+############################################################
+# Default Logging Configuration File
+#
+# You can use a different file by specifying a filename
+# with the java.util.logging.config.file system property.
+# For example java -Djava.util.logging.config.file=myfile
+############################################################
+
+############################################################
+# Global properties
+############################################################
+
+# "handlers" specifies a comma separated list of log Handler
+# classes. These handlers will be installed during VM startup.
+# Note that these classes must be on the system classpath.
+# By default we only configure a ConsoleHandler, which will only
+# show messages at the INFO and above levels.
+#handlers= java.util.logging.ConsoleHandler
+
+# To also add the FileHandler, use the following line instead.
+#handlers= java.util.logging.FileHandler, java.util.logging.ConsoleHandler
+
+# Default global logging level.
+# This specifies which kinds of events are logged across
+# all loggers. For any given facility this global level
+# can be overriden by a facility specific level
+# Note that the ConsoleHandler also has a separate level
+# setting to limit messages printed to the console.
+.level= INFO
+
+############################################################
+# Handler specific properties.
+# Describes specific configuration info for Handlers.
+############################################################
+
+# default file output is in user's home directory.
+java.util.logging.FileHandler.pattern = %h/java%u.log
+java.util.logging.FileHandler.limit = 50000
+java.util.logging.FileHandler.count = 1
+java.util.logging.FileHandler.formatter = java.util.logging.XMLFormatter
+
+# Limit the message that are printed on the console to INFO and above.
+java.util.logging.ConsoleHandler.level = INFO
+java.util.logging.ConsoleHandler.formatter = java.util.logging.SimpleFormatter
+
+
+############################################################
+# Facility specific properties.
+# Provides extra control for each logger.
+############################################################
+
+# For example, set the com.xyz.foo logger to only log SEVERE
+# messages:
+#com.xyz.foo.level = SEVERE
diff --git a/systests/transport-hc5/src/test/resources/org/apache/cxf/systest/hc5/http/greeting.wsdl b/systests/transport-hc5/src/test/resources/org/apache/cxf/systest/hc5/http/greeting.wsdl
new file mode 100644
index 0000000000..c12bdfe88a
--- /dev/null
+++ b/systests/transport-hc5/src/test/resources/org/apache/cxf/systest/hc5/http/greeting.wsdl
@@ -0,0 +1,166 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ 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.
+-->
+<wsdl:definitions xmlns="http://schemas.xmlsoap.org/wsdl/" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:tns="http://apache.org/hello_world" xmlns:x1="http://apache.org/hello_world/types" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" name="HelloWorld" targetNamespace="http://apache.org/hello_world">
+ <wsdl:types>
+ <schema xmlns="http://www.w3.org/2001/XMLSchema" xmlns:tns="http://apache.org/hello_world/types" targetNamespace="http://apache.org/hello_world/types" elementFormDefault="qualified">
+ <simpleType name="MyStringType">
+ <restriction base="string">
+ <maxLength value="30"/>
+ </restriction>
+ </simpleType>
+ <element name="sayHi">
+ <complexType/>
+ </element>
+ <element name="sayHiResponse">
+ <complexType>
+ <sequence>
+ <element name="responseType" type="string"/>
+ </sequence>
+ </complexType>
+ </element>
+ <element name="greetMe">
+ <complexType>
+ <sequence>
+ <element name="requestType" type="tns:MyStringType"/>
+ </sequence>
+ </complexType>
+ </element>
+ <element name="greetMeResponse">
+ <complexType>
+ <sequence>
+ <element name="responseType" type="string"/>
+ </sequence>
+ </complexType>
+ </element>
+ <element name="pingMe">
+ <complexType/>
+ </element>
+ <element name="pingMeResponse">
+ <complexType/>
+ </element>
+ <element name="faultDetail">
+ <complexType>
+ <sequence>
+ <element name="minor" type="short"/>
+ <element name="major" type="short"/>
+ </sequence>
+ </complexType>
+ </element>
+ </schema>
+ </wsdl:types>
+ <wsdl:message name="sayHiRequest">
+ <wsdl:part element="x1:sayHi" name="in"/>
+ </wsdl:message>
+ <wsdl:message name="sayHiResponse">
+ <wsdl:part element="x1:sayHiResponse" name="out"/>
+ </wsdl:message>
+ <wsdl:message name="greetMeRequest">
+ <wsdl:part element="x1:greetMe" name="in"/>
+ </wsdl:message>
+ <wsdl:message name="greetMeResponse">
+ <wsdl:part element="x1:greetMeResponse" name="out"/>
+ </wsdl:message>
+ <wsdl:message name="pingMeRequest">
+ <wsdl:part name="in" element="x1:pingMe"/>
+ </wsdl:message>
+ <wsdl:message name="pingMeResponse">
+ <wsdl:part name="out" element="x1:pingMeResponse"/>
+ </wsdl:message>
+ <wsdl:message name="pingMeFault">
+ <wsdl:part name="faultDetail" element="x1:faultDetail"/>
+ </wsdl:message>
+ <wsdl:portType name="Greeter">
+ <wsdl:operation name="sayHi">
+ <wsdl:input message="tns:sayHiRequest" name="sayHiRequest"/>
+ <wsdl:output message="tns:sayHiResponse" name="sayHiResponse"/>
+ </wsdl:operation>
+ <wsdl:operation name="greetMe">
+ <wsdl:input message="tns:greetMeRequest" name="greetMeRequest"/>
+ <wsdl:output message="tns:greetMeResponse" name="greetMeResponse"/>
+ </wsdl:operation>
+ <wsdl:operation name="pingMe">
+ <wsdl:input name="pingMeRequest" message="tns:pingMeRequest"/>
+ <wsdl:output name="pingMeResponse" message="tns:pingMeResponse"/>
+ <wsdl:fault name="pingMeFault" message="tns:pingMeFault"/>
+ </wsdl:operation>
+ </wsdl:portType>
+ <wsdl:binding name="Greeter_SOAPBinding" type="tns:Greeter">
+ <soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
+ <wsdl:operation name="sayHi">
+ <soap:operation soapAction="" style="document"/>
+ <wsdl:input name="sayHiRequest">
+ <soap:body use="literal"/>
+ </wsdl:input>
+ <wsdl:output name="sayHiResponse">
+ <soap:body use="literal"/>
+ </wsdl:output>
+ </wsdl:operation>
+ <wsdl:operation name="greetMe">
+ <soap:operation soapAction="" style="document"/>
+ <wsdl:input name="greetMeRequest">
+ <soap:body use="literal"/>
+ </wsdl:input>
+ <wsdl:output name="greetMeResponse">
+ <soap:body use="literal"/>
+ </wsdl:output>
+ </wsdl:operation>
+ <wsdl:operation name="pingMe">
+ <soap:operation style="document"/>
+ <wsdl:input>
+ <soap:body use="literal"/>
+ </wsdl:input>
+ <wsdl:output>
+ <soap:body use="literal"/>
+ </wsdl:output>
+ <wsdl:fault name="pingMeFault">
+ <soap:fault name="pingMeFault" use="literal"/>
+ </wsdl:fault>
+ </wsdl:operation>
+ </wsdl:binding>
+ <wsdl:service name="SOAPService">
+ <wsdl:port binding="tns:Greeter_SOAPBinding" name="Mortimer">
+ <soap:address location="http://localhost:9000/Mortimer"/>
+ </wsdl:port>
+ <wsdl:port binding="tns:Greeter_SOAPBinding" name="Tarpin">
+ <soap:address location="https://localhost:9003/Tarpin"/>
+ </wsdl:port>
+ <wsdl:port binding="tns:Greeter_SOAPBinding" name="Rethwel">
+ <soap:address location="http://localhost:9004/Rethwel"/>
+ </wsdl:port>
+ <wsdl:port binding="tns:Greeter_SOAPBinding" name="Gordy">
+ <soap:address location="https://localhost:9001/Gordy"/>
+ </wsdl:port>
+ <wsdl:port binding="tns:Greeter_SOAPBinding" name="Bethal">
+ <soap:address location="https://localhost:9002/Bethal"/>
+ </wsdl:port>
+ <wsdl:port binding="tns:Greeter_SOAPBinding" name="Hurlon">
+ <soap:address location="http://localhost:9006/Hurlon"/>
+ </wsdl:port>
+ <wsdl:port binding="tns:Greeter_SOAPBinding" name="Poltim">
+ <soap:address location="https://localhost:9005/Poltim"/>
+ </wsdl:port>
+ <wsdl:port binding="tns:Greeter_SOAPBinding" name="Abost">
+ <soap:address location="https://localhost:9007/Abost"/>
+ </wsdl:port>
+ <wsdl:port binding="tns:Greeter_SOAPBinding" name="Morpit">
+ <soap:address location="https://localhost:9008/Morpit"/>
+ </wsdl:port>
+ </wsdl:service>
+</wsdl:definitions>