Jetty (9.2.13) HTTP client with Socks4Proxy hangs - java

I'm using Burp's proxy server which is running in background.
I have inserted the cacert.der into my java trust store to which my eclipse is pointing to.
Now I have the following code :
...........................................................................
SslContextFactory sslContextFactory = new SslContextFactory();
HttpClient httpClient = new HttpClient(sslContextFactory);
httpClient.start();
Address address = new Address("127.0.0.1",8082);
Socks4Proxy socks4Proxy = new Socks4Proxy(address, true);
proxyConfiguration.getProxies().add(socks4Proxy);
Request request = httpClient.newRequest(
new URI("https://google.com"));
request.method(HttpMethod.GET);
ContentResponse contentResponse = request.send();
System.out.println(contentResponse.getContentAsString());
...........................................................................
The above code is giving me the following error :
Exception in thread "main" java.util.concurrent.ExecutionException: java.io.IOException: SOCKS4 tunnel failed with code 84
at org.eclipse.jetty.client.util.FutureResponseListener.getResult(FutureResponseListener.java:118)
at org.eclipse.jetty.client.util.FutureResponseListener.get(FutureResponseListener.java:101)
at org.eclipse.jetty.client.HttpRequest.send(HttpRequest.java:653)
at Get.main(Get.java:43)
...............................................................................
Can anyone suggest me how to resolve this ??

Related

Java Apache HTTP 401 response returned with correct credentials

I'm trying to hit a REST API link using Apache HttpClient but I keep getting a 401 error returned. I can login when I go to the URL in browser, after being prompted for a password. The code I'm using is below:
CredentialsProvider provider = new BasicCredentialsProvider();
UsernamePasswordCredentials credentials = new UsernamePasswordCredentials(creds.get(0), creds.get(1));
provider.setCredentials(AuthScope.ANY, credentials);
AuthCache authCache = new BasicAuthCache();
authCache.put(new HttpHost(uri.getHost(), uri.getPort(), "https"), new BasicScheme());
BasicHttpContext context = new BasicHttpContext();
context.setAttribute(ClientContext.CREDS_PROVIDER, provider);
context.setAttribute(ClientContext.AUTH_CACHE, authCache);
DefaultHttpClient client = new DefaultHttpClient();
client.setHttpRequestRetryHandler(new DefaultHttpRequestRetryHandler());
client.setCredentialsProvider(provider);
HttpResponse response = null;
try
{
// response = client.execute(new HttpGet(uri));
response = client.execute(new HttpGet(uri), context);
}
catch(IOException e)
{
logger.error("Error running authenticated get request: " + e);
}
I'm using HttpClient 4.2.3 and unfortunately I'm not able to upgrade this.
Any help would be appreciated! Thanks!
EDIT: turns out I need to supply the certificate, like using -cacert in curl, however I can't find an example of this!
Since you need to provide a certificate maybe this can help:
http://hc.apache.org/httpcomponents-client-4.2.x/httpclient/examples/org/apache/http/examples/client/ClientCustomSSL.java
I think that example complies with 4.2.3 .

CORS with Embedded Jetty HTTPS

I want to allow CORS for Embedded Jetty HTTPS, but the following code is not working. I managed to make the code work for HTTP using the following code.
public class EmbeddingJettyWithServlet {
public static void main(String[] args) throws Exception {
// Setup Threadpool for multiple server connections
QueuedThreadPool threadPool = new QueuedThreadPool();
threadPool.setMaxThreads(500);
//ThreadPool Server
Server server = new Server(threadPool);
// Configure jetty.home
String home = ".";
// Configure ports for http
ServerConnector http = new ServerConnector(server);
http.setPort(9889);
http.setIdleTimeout(30000);
// Scheduler
server.addBean(new ScheduledExecutorScheduler());
//Thread.currentThread().setPriority(Thread.MAX_PRIORITY);
// HTTPS Configuration
HttpConfiguration https = new HttpConfiguration();
https.addCustomizer(new SecureRequestCustomizer());
SslContextFactory sslContextFactory = new SslContextFactory();
sslContextFactory.setKeyStorePath(home + "/keystore.jks");
sslContextFactory.setKeyStorePassword("XXXXXXXXXX");
sslContextFactory.setKeyManagerPassword("XXXXXXXXXXX");
ServerConnector sslConnector = new ServerConnector(server,
new SslConnectionFactory(sslContextFactory, "http/1.1"),
new HttpConnectionFactory(https));
sslConnector.setPort(9888);
server.setConnectors(new Connector[] { http, sslConnector });
ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS);
context.setContextPath("/kibitz");
// Enable CORS - cross origin resource sharing (for http and https)
FilterHolder cors = new FilterHolder();
cors.setInitParameter("allowedOrigins", "*");
cors.setInitParameter("allowedHeaders", "*");
cors.setInitParameter("allowedMethods", "GET, POST");
cors.setFilter(new CrossOriginFilter());
context.addFilter(cors, "*", EnumSet.of(DispatcherType.REQUEST, DispatcherType.ASYNC, DispatcherType.INCLUDE));
server.setHandler(context);
server.start();
server.join();
}
But I can't get the HTTPS on port 9888 to work. Help greatly appreciated!
#Joakim Erdfelt was correct in that in my case, it was a keystore problem. After fumbling around with this, I discovered that the problem was my Firefox browser and untrusted certificates. Firefox, rather than giving the "Get Me Out of Here" message that it would give if you go to the https:// URL directly, the Javascript console, instead, gives the "Cross-Origin Request Blocked" error if your website is trying to access via a port.
In order to use https://, you must get a certificate from a trusted Certificate Authority and install it into your keystore. Some browsers will block the request if you generate your own certificate. This article's tremendously helpful in setting up your keystore correctly: http://www.eclipse.org/jetty/documentation/current/configuring-ssl.html.
Lets start with using the HttpConfiguration properly.
// Setup Threadpool for multiple server connections
QueuedThreadPool threadPool = new QueuedThreadPool();
threadPool.setMaxThreads(500);
//ThreadPool Server
Server server = new Server(threadPool);
int port = 9889;
int portSecure = 9888;
// Configure jetty.home
String home = ".";
// HTTP Configuration
HttpConfiguration http_config = new HttpConfiguration();
http_config.setSecureScheme("https");
http_config.setSecurePort(portSecure);
// Configure Connector for http
ServerConnector http = new ServerConnector(server,
new HttpConnectionFactory(http_config));
http.setPort(port);
http.setIdleTimeout(30000);
// HTTPS Configuration
HttpConfiguration https_config = new HttpConfiguration(http_config);
https_config.addCustomizer(new SecureRequestCustomizer());
SslContextFactory sslContextFactory = new SslContextFactory();
sslContextFactory.setKeyStorePath(home + "/keystore.jks");
sslContextFactory.setKeyStorePassword("XXXXXXXXXX");
sslContextFactory.setKeyManagerPassword("XXXXXXXXXXX");
ServerConnector sslConnector = new ServerConnector(server,
new SslConnectionFactory(sslContextFactory, "http/1.1"),
new HttpConnectionFactory(https_config));
sslConnector.setPort(portSecure);
server.setConnectors(new Connector[] { http, sslConnector });
Your code had nothing defining what port was considered secure, and it also did not carry over the http configuration to the https side.
That should help in some regard. However if you don't have your keystore created properly, then no amount of Jetty side configuration will help.

Is the ProxyFactory replacement in RESTEasy thread safe?

I developed a service in RESTEasy using ProxyFactory and ClientExecutor like this:
PoolingClientConnectionManager connectionManager = new PoolingClientConnectionManager();
DefaultHttpClient httpClient = new DefaultHttpClient(connectionManager);
HttpParams params = httpClient.getParams();
HttpConnectionParams.setConnectionTimeout(params, 5000);
HttpConnectionParams.setSoTimeout(params, 5000);
ClientExecutor clientExecutor = new ApacheHttpClient4Executor(httpClient);
MyClass client = ProxyFactory.create(MyClass.class, "http://www.example.com", clientExecutor);
It always worked perfectly. After RESTEasy deprecated both ClientExecutor and ProxyFactory, they provided a new ResteasyClient for external connections, but I don't know if this new ResteasyClient is threadsafe. This is the new sample code from the documentation:
ResteasyClient client = new ResteasyClientBuilder().build();
ResteasyWebTarget target = client.target("http://example.com/base/uri");
SimpleClient simple = target.proxy(SimpleClient.class);
UPDATE: I used the code with the ResteasyClient and I got many of these errors:
javax.ws.rs.ProcessingException: Unable to invoke request
Caused by
java.lang.IllegalStateException: Invalid use of BasicClientConnManager: connection still allocated. Make sure to release the connection before allocating another one.
We use this:
final ResteasyClient client = new ResteasyClientBuilder()
.connectionPoolSize(10)
.maxPooledPerRoute(5)
.build();
And after debugging I found out that (at least in our situation) the RESTEasy client uses the ThreadSafeClientConnManager by default so I think there is no need to specify a different one although according to the JavaDoc it is deprecated in favour of PoolingHttpClientConnectionManager (note the extra Http). But this has been fixed in RESTEasy client 3.0.5.Final: https://issues.jboss.org/browse/RESTEASY-948
It's a jungle of HTTP connection managers out there..
This worked for me. Just needed to find the hook into setting up the Apache HTTP engine. Mostly based on RestEasy 3.0.5.Final API
public static Object setupServiceProxy(#NotNull Class responseClass) {
ResteasyProviderFactory factory = ResteasyProviderFactory.getInstance();
ResteasyClientBuilder builder = new ResteasyClientBuilder().providerFactory(factory);
ResteasyClient client = builder.httpEngine(setupHttpDefaults()).build();
ResteasyWebTarget target = client.target(url);
return target.proxy(responseClass);
}
public static ClientHttpEngine setupHttpDefaults() {
PoolingClientConnectionManager connectionManager = new PoolingClientConnectionManager();
DefaultHttpClient httpClient = new DefaultHttpClient(connectionManager);
HttpParams params = httpClient.getParams();
HttpConnectionParams.setConnectionTimeout(params, 30000);
HttpConnectionParams.setSoTimeout(params, 30000);
BasicHttpContext localContext = new BasicHttpContext();
return new ApacheHttpClient4Engine(httpClient, localContext);
}

CXF SOAP Client with NTLM to SharePoint

I am writing a SOAP client using CXF Framework (version: 2.7.8) for SharePoint 2007. I have followed the online documentation for adding NTLM support here. I have the client working and tracing the HTTP session shows that NTLM credentials are being sent, however, I am still receiving a 401 Unauthorized response.
Code:
Lists listService = new Lists();
ListsSoap port = listService.getListsSoap();
BindingProvider bp = (BindingProvider) port;
bp.getRequestContext().put("use.async.http.conduit", Boolean.TRUE);
Credentials creds = new NTCredentials(USER, PASS, "", DOMAIN);
bp.getRequestContext().put(Credentials.class.getName(), creds);
Client client = ClientProxy.getClient(proxy);
HTTPConduit http = (HTTPConduit) client.getConduit();
HTTPClientPolicy httpClientPolicy = new HTTPClientPolicy();
httpClientPolicy.setConnectionTimeout(36000);
httpClientPolicy.setAllowChunking(false);
httpClientPolicy.setAutoRedirect(true);
http.setClient(httpClientPolicy);
// Build request and execute
Interestingly, I wrote a similar client using HTTP PUT for WebDAV to upload documents using Apache HTTPClient library, and was able to successfully authenticate using NTLM. Also, I was able to use SOAPUI to invoke the same Lists web service I am trying to build the Java client for and it successfully authenticated using NTLM as well.
I'm assuming the implementation of NTLM is different between CXF and HTTPClient. Any thoughts on what is wrong with my CXF implementation? Or how I can get it to mirror the HTTPClient implementation?
Please try this way!
HTTPConduit http = (HTTPConduit)client.getConduit();
AsyncHTTPConduit conduit = (AsyncHTTPConduit)http;
DefaultHttpAsyncClient defaultHttpAsyncClient;
defaultHttpAsyncClient = conduit.getHttpAsyncClient();
defaultHttpAsyncClient.getCredentialsProvider().setCredentials( AuthScope.ANY,
new NTCredentials( USER,PWD, "", DOM ) );
conduit.getClient().setAllowChunking( false );
conduit.getClient().setAutoRedirect( true );
#lamarvannoy, I also got this error. But I found another way. You don't need to cast HTTPConduit to AsyncHTTPConduit. Let's try this stuff:
public class Test {
static final String kuser = "yourDomain\\username";
static final String kpass = "yourPassword";
static class MyAuthenticator extends Authenticator {
public PasswordAuthentication getPasswordAuthentication() {
System.err.println("Feeding username and password for " + getRequestingScheme());
return (new PasswordAuthentication(kuser, kpass.toCharArray()));
}
}
public static void main(String[] args) throws Exception {
Authenticator.setDefault(new MyAuthenticator());
Lists listService = new Lists();
ListsSoap port = listService.getListsSoap();
Client client = ClientProxy.getClient(port);
HTTPConduit http = (HTTPConduit) client.getConduit();
HTTPClientPolicy httpClientPolicy = new HTTPClientPolicy();
httpClientPolicy.setConnectionTimeout(36000);
httpClientPolicy.setAllowChunking(false);
http.setClient(httpClientPolicy);
String listName = "S030_main";
String rowLimit = "150";
ArrayList<String> listColumnNames = new ArrayList<String>();
listColumnNames.add("Title");
Test.displaySharePointList(port, listName, listColumnNames, rowLimit);
}
}
You may find the implementation of displaySharePointList() method in this post: http://davidsit.wordpress.com/2010/02/10/reading-a-sharepoint-list-with-java-tutorial/
I hope this will safe your and others time.
This works for me:
Client client = ClientProxy.getClient(port);
AsyncHTTPConduit conduit = (AsyncHTTPConduit)client.getConduit();
AuthorizationPolicy authorization = conduit.getAuthorization();
authorization.setUserName("domain\\username");
authorization.setPassword("password");
Actually this works for both NTLM and Basic
This is what I had to do to get mine to work:
// Include a version of WSDL in class path, make URL point to that
URL url = MyClient.class.getResource("previouslydownloaded.wsdl");
MyCxFService ws = new MyCxFService(url);
MyCxfClient client = ws.getMyCxfServicePort();
BindingProvider prov = ((BindingProvider) client);
Binding binding = prov.getBinding();
// Set Username and Password
if ((this.user != null) && (!this.user.isEmpty())) {
prov.getRequestContext().put(BindingProvider.USERNAME_PROPERTY, this.user);
prov.getRequestContext().put(BindingProvider.PASSWORD_PROPERTY, this.passwd);
}
// Get address from config file to get rid error caused by using wsdl file:
// Caused by: java.lang.NullPointerException
// at org.apache.cxf.transport.http.URLConnectionHTTPConduit.createConnection(URLConnectionHTTPConduit.java:104)
prov.getRequestContext().put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, this.portAddress);
Hope that might help someone.

Unable to get Proxy working with Socket

I am trying to get Proxy working with Socket. But everytime I tried, it would returned a "Exception in thread "pool-1-thread-1" java.lang.IllegalArgumentException: Invalid Proxy" exception error
at java.net.Socket.(Socket.java:131)
But if its Proxy.Type.SOCKS, it works.
public void Test()
{
Socket s = null;
SocketAddress addr = null;
Proxy proxy = null;
addr = new InetSocketAddress("127.0.0.1", 8080);
proxy = new Proxy(Proxy.Type.HTTP, addr);
socket = new Socket(proxy); // This is the line that is triggering the exception
}
Sadly this is a bug in (Oracle) Java - only DIRECT and SOCKS proxy is supported for Socket. See http://bugs.sun.com/view_bug.do?bug_id=6370908.

Categories