cURL app using Java - java

Does anyone have a good tutorial on how to write a java or javafx cURL application? I have seen tons of tutorials on how to initiate an external call to say like an XML file, but the XML feed I am trying to retrieve calls for you to submit the username and password before being able to retrieve the XML feed.

What are you trying to accomplish? Are you trying to retrieve a XML feed over HTTP?
In that case I suggest you to take a look at Apache HttpClient. It offers similair functionality as cURL but in a pure Java way (cURL is a native C application). HttpClient supports multiple authentication mechanisms. For example you can submit a username/password using Basic Authentication like this:
public static void main(String[] args) throws Exception {
DefaultHttpClient httpclient = new DefaultHttpClient();
httpclient.getCredentialsProvider().setCredentials(
new AuthScope("localhost", 443),
new UsernamePasswordCredentials("username", "password"));
HttpGet httpget = new HttpGet("https://localhost/protected");
System.out.println("executing request" + httpget.getRequestLine());
HttpResponse response = httpclient.execute(httpget);
HttpEntity entity = response.getEntity();
System.out.println("----------------------------------------");
System.out.println(response.getStatusLine());
if (entity != null) {
System.out.println("Response content length: " + entity.getContentLength());
}
if (entity != null) {
entity.consumeContent();
}
// When HttpClient instance is no longer needed,
// shut down the connection manager to ensure
// immediate deallocation of all system resources
httpclient.getConnectionManager().shutdown();
}
Check the website for more examples.

Related

Issue with wsimport authentication when generating SOAP Java client

I use the following command to generate web service client files for java.
wsimport -keep http://test.com/test?wsdl -xauthfile auth.txt
The following was in auth.txt
http://user:password#ip:port//path
But, the password was having special characters like abcw#sdsds.
So I was getting wrong format error. So I have encoded password like abcw%40sdsds. But, now got authentication error due to wrong password because of parsing.
Is there any ways to handle this scenario ?
After checking online I found this bug was actually fixed in the latest version. But I still get the same issue. You can refer to the following links for information on the bug.
https://github.com/javaee/metro-jax-ws/issues/1101
So I finally made custom HTTP request with NTLM authentication using HTTP Client in Java.
String bodyAsString = ""; //Provide Input SOAP Message
CredentialsProvider credsProvider = new BasicCredentialsProvider();
credsProvider.setCredentials(AuthScope.ANY,
new NTCredentials("UserName", "Password", "Host", "Domain"));
HttpClient client = HttpClientBuilder.create().setDefaultCredentialsProvider(credsProvider).build();
HttpPost post = new HttpPost("URL"); //Provide Request URL
try
{
StringEntity input = new StringEntity(bodyAsString);
input.setContentType("text/xml; charset=utf-8");
post.setEntity(input);
post.setHeader("Content-type", "text/xml; charset=utf-8");
post.setHeader("SOAPAction", ""); //Provide Soap action
org.apache.http.HttpResponse response = client.execute(post);
HttpEntity responseEntity = response.getEntity();
if (responseEntity != null)
{
return EntityUtils.toString(responseEntity);
}
}
I got the above solution from the following github link
https://github.com/sujithtw/soapwithntlm

Android http post advanced request with body on hostmachine

I would like to do a HTTP post request from my virtual android device on the hostmachine.
Below you'll see an image on how I post, by using the old WebFetch tool.
I don't know what URL to use for calling the hostmachine?
I got no idea how my body string can be used an input?
Does anybody have an idea on how to solve this?
If you want to connect to the computer which is running the Android simulator, use the IP address 10.0.2.2. You can read more about it here.
Also check out the accepted answer in following question to see how json can be send as post data:
How to send POST request in JSON using HTTPClient?
you can use following code to make HTTP get request:
try {
HttpClient client = new DefaultHttpClient();
String getURL = "http://10.0.2.2:port/your_path_with_parameter";
HttpGet get = new HttpGet(getURL);
HttpResponse responseGet = client.execute(get);
HttpEntity resEntityGet = responseGet.getEntity();
if (resEntityGet != null) {
//do something with the response
Log.i("GET RESPONSE",EntityUtils.toString(resEntityGet));
}
} catch (Exception e) {
e.printStackTrace();
}

Authenticating to sharepoint with kerberos from a java HttpClient

I have a linux\java6 client that will authenticate to sharepoint2010 with NTLM and then send HTTP REST web services using Apache Commons HttpClient.
I can do this with NTLM , but I want to use the same REST API to access sharepoint 2010 that uses kerberos auth.
Any examples how to authenticate and send REST over HTTP with a kerberos sharepoint?
(preferably using HttpClient)
p.s.
I dont have access to sharepoint code, but i do have access to sharepoint admin configurations.
This is roughly how I authenticate with NTLM:
HttpClient httpClient = new HttpClient(new SimpleHttpConnectionManager(true));
AuthPolicy.registerAuthScheme(AuthPolicy.NTLM, JCIFS_NTLMScheme.class);
String localHostName = Inet4Address.getLocalHost().getHostName();
authscope = new AuthScope(uri.getHost(), AuthScope.ANY_PORT);
httpClient.getState().setCredentials(authscope,new NTCredentials(
getUsername(),getPassword(),localHostName,getDomain()));
// after the initial ntlm auth I can call my REST service with "httpClient.executeMethod"
int status = httpClient.executeMethod(new GetMethod(accessURI + "/sitecollection/info"));
Please confirm that your environment is correctly setup for Kerberos, this can be achieved by running kinit. If this fails you will need to ensure that your krb5.ini (windows) or krb5.conf (linux) are setup to point to your domain controller correctly.
Once you have confirmed that Kerberos is functional you can use the example code from HttpClient as pasted below.
Please note that there are many issues that can cause Kerberos to fail, such as time synchronisation, supported encryption types, trust relationships across domain forests and it's also worth ensuring that your client is on a seperate box to the server.
Here is the example code which is available in the HttpClient download, you will need to ensure your JAAS configuration and krb5.conf or ini are correct!
public class ClientKerberosAuthentication {
public static void main(String[] args) throws Exception {
System.setProperty("java.security.auth.login.config", "login.conf");
System.setProperty("java.security.krb5.conf", "krb5.conf");
System.setProperty("sun.security.krb5.debug", "true");
System.setProperty("javax.security.auth.useSubjectCredsOnly","false");
DefaultHttpClient httpclient = new DefaultHttpClient();
try {
httpclient.getAuthSchemes().register(AuthPolicy.SPNEGO, new SPNegoSchemeFactory());
Credentials use_jaas_creds = new Credentials() {
public String getPassword() {
return null;
}
public Principal getUserPrincipal() {
return null;
}
};
httpclient.getCredentialsProvider().setCredentials(
new AuthScope(null, -1, null),
use_jaas_creds);
HttpUriRequest request = new HttpGet("http://kerberoshost/");
HttpResponse response = httpclient.execute(request);
HttpEntity entity = response.getEntity();
System.out.println("----------------------------------------");
System.out.println(response.getStatusLine());
System.out.println("----------------------------------------");
if (entity != null) {
System.out.println(EntityUtils.toString(entity));
}
System.out.println("----------------------------------------");
// This ensures the connection gets released back to the manager
EntityUtils.consume(entity);
} finally {
// When HttpClient instance is no longer needed,
// shut down the connection manager to ensure
// immediate deallocation of all system resources
httpclient.getConnectionManager().shutdown();
}
}
}

Consuming web service & storing cookies

This method is used to consume a web service which I also control. The web service sets cookies to keep the user logged in.
This all works fine through a browser. i.e. I can call the login url, it will cookie my browser, and subsequent access to the web service recognizes my cookies.
In android, I can get a successful return on my login, but the cookies do not seem to be setting.
You can see where this code prints the cookie data to the output. It prints the cookie when it hits the login script, but for subsequent calls to this function, it does not recognize the cookie anymore.
Here's the code I'm using, I started from an example someone else posted:
private JSONObject getResponse(String func, List<NameValuePair> args) throws Exception {
HttpClient httpclient = new DefaultHttpClient();
try {
// Create a local instance of cookie store
CookieStore cookieStore = new BasicCookieStore();
// Create local HTTP context
HttpContext localContext = new BasicHttpContext();
// Bind custom cookie store to the local context
localContext.setAttribute(ClientContext.COOKIE_STORE, cookieStore);
HttpPost put= new HttpPost("http://example.com/api/" + func);
if (args != null) {
put.setEntity(new UrlEncodedFormEntity(args));
}
System.out.println("executing request " + put.getURI());
// Pass local context as a parameter
HttpResponse response = httpclient.execute(put, localContext);
HttpEntity entity = response.getEntity();
System.out.println("----------------------------------------");
System.out.println(response.getStatusLine());
if (entity != null) {
System.out.println("Response content length: " + entity.getContentLength());
}
List<Cookie> cookies = cookieStore.getCookies();
for (int i = 0; i < cookies.size(); i++) {
System.out.println("Local cookie: " + cookies.get(i));
}
// Consume response content
//EntityUtils.consume(entity);
System.out.println("----------------------------------------");
InputStream instream = entity.getContent();
String result = convertStreamToString(instream);
instream.close();
entity.consumeContent();
System.out.println("JSON Output: " + result);
return new JSONObject(result);
} finally {
// When HttpClient instance is no longer needed,
// shut down the connection manager to ensure
// immediate deallocation of all system resources
httpclient.getConnectionManager().shutdown();
}
}
That might be because your HttpClient and CookieStore are local to getResponse. Try making them global so they persist onto subsequent calls.
When you are trying to access locked content on a url call you need to manually set a cookie for the next coming call, which can be done using:
HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection();
httpURLConnection.setInstanceFollowRedirects(false);
httpURLConnection.setRequestProperty("Host", domainOfYourCookie);
httpURLConnection.setRequestProperty("Cookie", valueOfYourCookie);
I have written another answer regarding this topic, which you can find here.

Getting Unexpected 401 from Apache HTTPClient Basic Auth

I'm attempting to do basic auth with Apache HTTPClient 4.x using the example from the site, the only change being that I've extracted some details out into constants, however I'm not getting the results I was hoping for.
Namely, with the logging turned up to debug, I'm getting: "DEBUG main client.DefaultHttpClient:1171 - Credentials not found", followed by a 401 error from the server.
I've manually validated that the credentials I've configured are correct, and the "Credentials not found" message leads me to believe the credentials were never passed in the request.
Any thoughts on what I might be doing wrong?
DefaultHttpClient httpClient = new DefaultHttpClient();
httpClient.getCredentialsProvider().setCredentials(
new AuthScope(API_HOST, API_PORT),
new UsernamePasswordCredentials(API_USERNAME, API_PASSWORD));
HttpGet httpget = new HttpGet(API_TEST_URL);
System.out.println("executing request" + httpget.getRequestLine());
HttpResponse response = httpClient.execute(httpget);
HttpEntity entity = response.getEntity();
System.out.println("----------------------------------------");
System.out.println(response.getStatusLine());
if (entity != null) {
System.out.println("Response content length: " + entity.getContentLength());
}
if (entity != null) {
entity.consumeContent();
}
httpClient.getConnectionManager().shutdown();
Are you sure the AuthScope is set correctly? Try setting it like this just to see if the problem is there
new AuthScope(AuthScope.ANY_HOST, AuthScope.ANY_PORT)

Categories