3

Please note that I've tested the following in SOAPUI and it appears to work as expected (i.e. returning a 200 status) using the same URL and Authorization credentials. The fact that it works OK in SOAPUI makes me think I should be doing something specific when building my request to handle the fact that it's https.

Attempting to POST to a URL using DefaultHttpClient (v4.2.3) using the following method:

String requestUrl = "https://test.host.name:9093/ws/simple/serviceName";
HttpPost httpPost = new HttpPost(requestUrl);

String username = "username@domainname";
String password = "pass-word-string";
String usernameAndPassword = username + ":" + password;
String encodedUserNameAndPassword = new sun.misc.BASE64Encoder().encode(usernameAndPassword.getBytes());
httpPost.setHeader("Authorization", encodedUserNameAndPassword);

DefaultHttpClient httpClient = new DefaultHttpClient();
HttpResponse response = httpClient.execute(httpPost);
System.out.println(response.getStatusLine().toString());

HttpEntity entity = response.getEntity();           
String responseString = EntityUtils.toString(entity, "UTF-8");
System.out.println(responseString);

EntityUtils.consume(entity);

The problem I'm having is that the server is responding with a 400 status and Bad Request message:

[DEBUG] wire - << "HTTP/1.1 400 Bad Request[\r][\n]"
[DEBUG] wire - << "Connection: close[\r][\n]"
[DEBUG] wire - << "Server: Jetty(6.1.26-boomi)[\r][\n]"
[DEBUG] wire - << "[\r][\n]"

If I remove the authentication part then I get a "401 Not Authorized" which at least indicates that the server is expecting my request:

[DEBUG] wire - << "HTTP/1.1 401 Unauthorized[\r][\n]"
[DEBUG] wire - << "WWW-Authenticate: Basic realm="BoomiBasicRealm"[\r][\n]"
[DEBUG] wire - << "Content-Type: text/html; charset=iso-8859-1[\r][\n]"
[DEBUG] wire - << "Cache-Control: must-revalidate,no-cache,no-store[\r][\n]"
[DEBUG] wire - << "Content-Length: 1396[\r][\n]"
[DEBUG] wire - << "Server: Jetty(6.1.26-boomi)[\r][\n]"

The server admin has said that he can see the following coming through to the server logs:

SSL renegotiate denied: java.nio.channels.SocketChannel[connected local=/192.168.20.86:9093 remote=/ip.ip.ip.ip:61356]”

The strange thing is that I've used the same code to post successfully to other URLs which are using https, albeit not using a different port in the address, and it works without an issue.

The server admin is looking at it from their end while I continue to investigate but the fact that it works in SOAPUI makes me think there is something I need to do differently.

I noticed that SOAPUI is using Apache-HttpClient v4.1.1 whereas I'm using 4.2.3 so I switched to 4.1.1 and it didn't make a difference. Therefore I'm guessing that SOAPUI is doing something different under the covers which I need to mimic.

Are there any SOAPUI devs out there who might be able to advise?

lee_mcmullen
  • 2,801
  • 32
  • 39
  • try to hit service URL with browser. Looks like problem in SSL certificate, not in Basic Authorization. – user1516873 Feb 07 '13 at 15:26
  • Hitting the URL in a browser doesn't throw any errors. The basic authorization part appears to be working ok. The problem is once I'm past the authorization part. – lee_mcmullen Feb 07 '13 at 15:35
  • Who issued server Sertificate? If server used self-signed cert, you can fetch if (from browser, for example), store somewhere on hard drive and add it to JRE cacert. `cd $JRE_HOME/lib/security` `keytool -importcert -keystore cacerts -file /path/to/CA.pem -alias test`. – user1516873 Feb 08 '13 at 06:43
  • It's a DigiCert High Assurance CA-3 certificate so not self-signed. – lee_mcmullen Feb 08 '13 at 11:14
  • i would suggest set property -Djavax.net.debug=all and run code again. Maybe it reveals something curious. – user1516873 Feb 08 '13 at 11:47
  • I've been through and followed the following article (http://docs.oracle.com/javase/1.5.0/docs/guide/security/jsse/ReadDebug.html) with -Djavax.net.debug=all enabled. All appears to be ok and yet the server still returns a response code 400. And yet when I POST to the same URL in SOAPUI, it works OK. – lee_mcmullen Feb 11 '13 at 14:46
  • Does the same code work for a http request? (without the s) – flup Feb 13 '13 at 15:14
  • The server I'm calling isn't accepting any requests over just http so I can't test. – lee_mcmullen Feb 14 '13 at 14:45
  • @lee_mcmullen Could you post request wire logs? – fglez Feb 26 '13 at 16:05
  • take a look at the SOAPUI HTTP log to see what it actually sending compared to what you are sending. – Martin Spamer Apr 19 '13 at 15:00

2 Answers2

0

Perhaps you should enable HttpClient's preemtive authorization instead of adding Authorization header by hand.

See also Preemptive Basic authentication with Apache HttpClient 4

Community
  • 1
  • 1
fglez
  • 8,422
  • 4
  • 47
  • 78
0

The sun Base64 encoder will add newlines after a certain number of characters. if your encoded username/password is too long, you will be sending a broken authorization header. trying removing any whitespace from the encode authorization value. (as a side note, you should always use an explicit encoding with String.getBytes())

String encodedUserNameAndPassword = new sun.misc.BASE64Encoder()
    .encode(usernameAndPassword.getBytes("UTF-8"))
    .replaceAll("\\s+", "");

That said, i'm pretty sure apache http client can handle this for you. You should probably be following this example.

jtahlborn
  • 52,909
  • 5
  • 76
  • 118