HTTPS connection with basic auth result into Unauthorized - java

I am trying to access Basecamp API from my Android/Java source code following way ....
import org.apache.http.HttpResponse;
import org.apache.http.StatusLine;
import org.apache.http.client.ResponseHandler;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.BasicResponseHandler;
import org.apache.http.impl.client.DefaultHttpClient;
import android.app.Activity;
import android.os.Bundle;
import android.webkit.WebView;
public class BCActivity extends Activity {
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
DefaultHttpClient httpClient = new DefaultHttpClient();
//final String url = "https://encrypted.google.com/webhp?hl=en"; //This url works
final String url = "https://username:password#projectsource.basecamphq.com/people.xml"; //This don't
HttpGet http = new HttpGet(url);
http.addHeader("Accept", "application/xml");
http.addHeader("Content-Type", "application/xml");
try {
// HttpResponse response = httpClient.execute(httpPost);
HttpResponse response = httpClient.execute(http);
StatusLine statusLine = response.getStatusLine();
System.out.println("statusLine : "+ statusLine.toString());
ResponseHandler <String> res = new BasicResponseHandler();
String strResponse = httpClient.execute(http, res);
System.out.println("________**_________________________\n"+strResponse);
System.out.println("\n________**_________________________\n");
} catch (Exception e) {
e.printStackTrace();
}
WebView myWebView = (WebView) this.findViewById(R.id.webView);
myWebView.loadUrl(url);//Here it works and displays XML response
}
}
This URL displays the response in WebView, but shows Unauthorized exception when I try to access through HttpClient as shown above.
Is this is right way to access Basecamp API through Android/Java?
or
Please provide me a right way to do so.

The HttpClient can't take the login creditals from the URI.
You have to give them with specified methods.
If you use HttpClient 4.x have a look on this:
http://hc.apache.org/httpcomponents-client-ga/tutorial/html/authentication.html
But notice if you don't want to use the new version on the HttpClient (Android uses version 3.x), you should look here:
http://hc.apache.org/httpclient-3.x/authentication.html
That was the theory, now we use them:
Basically we use HTTP, but if you want to use HTTPS, you have to edit the following assignment new HttpHost("www.google.com", 80, "http") into new HttpHost("www.google.com", 443, "https").
Furthermore you have to edit the host (www.google.com) for your concerns.
Notice: Only the full qualified domain name (FQDN) is needed not the full URI.
HttpClient 3.x:
package com.test;
import org.apache.http.HttpEntity;
import org.apache.http.HttpHost;
import org.apache.http.HttpResponse;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.util.EntityUtils;
import android.app.Activity;
import android.os.Bundle;
public class Test2aActivity extends Activity {
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
try {
HttpHost targetHost = new HttpHost("www.google.com", 80, "http");
DefaultHttpClient httpclient = new DefaultHttpClient();
try {
// Store the user login
httpclient.getCredentialsProvider().setCredentials(
new AuthScope(targetHost.getHostName(), targetHost.getPort()),
new UsernamePasswordCredentials("user", "password"));
// Create request
// You can also use the full URI http://www.google.com/
HttpGet httpget = new HttpGet("/");
// Execute request
HttpResponse response = httpclient.execute(targetHost, httpget);
HttpEntity entity = response.getEntity();
System.out.println(EntityUtils.toString(entity));
} finally {
httpclient.getConnectionManager().shutdown();
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
HttpClient 4.x:
Attention: You will need the new HttpClient from Apache and additionally you must rearrange the order, that the jar-file is before the Android library.
package com.test;
import org.apache.http.HttpEntity;
import org.apache.http.HttpHost;
import org.apache.http.HttpResponse;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.client.AuthCache;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.protocol.ClientContext;
import org.apache.http.impl.auth.BasicScheme;
import org.apache.http.impl.client.BasicAuthCache;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.protocol.BasicHttpContext;
import org.apache.http.util.EntityUtils;
import android.app.Activity;
import android.os.Bundle;
public class TestActivity extends Activity {
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
try {
HttpHost targetHost = new HttpHost("www.google.com", 80, "http");
DefaultHttpClient httpclient = new DefaultHttpClient();
try {
// Store the user login
httpclient.getCredentialsProvider().setCredentials(
new AuthScope(targetHost.getHostName(), targetHost.getPort()),
new UsernamePasswordCredentials("user", "password"));
// Create AuthCache instance
AuthCache authCache = new BasicAuthCache();
// Generate BASIC scheme object and add it to the local
// auth cache
BasicScheme basicAuth = new BasicScheme();
authCache.put(targetHost, basicAuth);
// Add AuthCache to the execution context
BasicHttpContext localcontext = new BasicHttpContext();
localcontext.setAttribute(ClientContext.AUTH_CACHE, authCache);
// Create request
// You can also use the full URI http://www.google.com/
HttpGet httpget = new HttpGet("/");
// Execute request
HttpResponse response = httpclient.execute(targetHost, httpget, localcontext);
HttpEntity entity = response.getEntity();
System.out.println(EntityUtils.toString(entity));
} finally {
httpclient.getConnectionManager().shutdown();
}
} catch (Exception e) {
e.printStackTrace();
}
}
}

Finally I got it How to glue the code shown in above answer ...
public static void performPost(String getUri, String xml) {
String serverName = "*******";
String username = "*******";
String password = "********";
String strResponse = null;
try {
HttpHost targetHost = new HttpHost(serverName, 443, "https");
DefaultHttpClient httpclient = new DefaultHttpClient();
try {
// Store the user login
httpclient.getCredentialsProvider().setCredentials(
new AuthScope(targetHost.getHostName(), targetHost.getPort()),
new UsernamePasswordCredentials(username, password));
// Create AuthCache instance
AuthCache authCache = new BasicAuthCache();
// Generate BASIC scheme object and add it to the local
// auth cache
BasicScheme basicAuth = new BasicScheme();
authCache.put(targetHost, basicAuth);
// Add AuthCache to the execution context
BasicHttpContext localcontext = new BasicHttpContext();
localcontext.setAttribute(ClientContext.AUTH_CACHE, authCache);
// Create request
// You can also use the full URI http://www.google.com/
HttpPost httppost = new HttpPost(getUri);
StringEntity se = new StringEntity(xml,HTTP.UTF_8);
se.setContentType("text/xml");
httppost.setEntity(se);
// Execute request
HttpResponse response = httpclient.execute(targetHost, httppost, localcontext);
HttpEntity entity = response.getEntity();
strResponse = EntityUtils.toString(entity);
StatusLine statusLine = response.getStatusLine();
Log.i(TAG +": Post","statusLine : "+ statusLine.toString());
Log.i(TAG +": Post","________**_________________________\n"+strResponse);
Log.i(TAG +": Post","\n________**_________________________\n");
} finally {
httpclient.getConnectionManager().shutdown();
}
} catch (Exception e) {
e.printStackTrace();
}
}
One very important thing How your library should be arranged and which libraries you will required ...
From Here you will find this libraries.
To add them in eclipse (Below Android sdk < 16)...
Project properties -> java build path -> Libraries -> Add external JARs
To arrange them in order in eclipse ...
Project properties -> java build path -> order and export
For above Android sdk >= 16 you will have to put these libraries into "libs" folder.

Appendix on the brilliant and very helpfull answer of CSchulz:
in http client 4.3 this:
localcontext.setAttribute(ClientContext.AUTH_CACHE, authCache);
does not work anymore (ClientContext.AUTH_CACHE is deprecated)
use:
import org.apache.http.client.protocol.HttpClientContext;
and
localcontext.setAttribute(HttpClientContext.AUTH_CACHE, authCache);
see http://hc.apache.org/httpcomponents-client-ga/httpclient/apidocs/org/apache/http/client/protocol/ClientContext.html
and:
http://hc.apache.org/httpcomponents-client-ga/httpclient/apidocs/org/apache/http/client/protocol/HttpClientContext.html

If you like to use the HttpClient 4.x as mentioned in the other answers you could also
use httpclientandroidlib. This is a converted stock HttpClient without apache.commons
and with Android LogCat support.

Related

representing curl command in java

what is the Java equivalent of the following curl command:
curl -u <username>:<password> -F "access=#svnaccess.txt" https://svn.xxx-xxx.de/upload.cgi
i try to update the access rules of a svn repository by uploading a .txt file to this url.
any help is much appreciated!
From your curl command you are using
-u to use basic auth with the provided username and password
-F which uses http verb post
# to load the contents of the file
The Java equivalent is to use HttpClient. However most examples are out of date with the current version. So as of 4.4.1 ...
Authentication is simplify a case of building HttpClients with a CredentialsProvider
CredentialsProvider credsProvider = new BasicCredentialsProvider();
credsProvider.setCredentials(
new AuthScope(server, (https ? 443:80)),
new UsernamePasswordCredentials("username", "password")
);
CloseableHttpClient httpclient = HttpClients
.custom()
.setDefaultCredentialsProvider(credsProvider)
.build();
To reproduce your use of -F to upload a file you will want to add something that implements org.apache.http.NameValuePair and you can then use UrlEncodedFormEntity with your file you want to upload.
List<NameValuePair> formparams = new ArrayList<NameValuePair>();
formparams.add(new FileNameValuePair("access", new File("./svnaccess.txt")));
UrlEncodedFormEntity entity = new UrlEncodedFormEntity(formparams, Consts.UTF_8);
httppost.setEntity(entity)
Runable Example
Example.java
import java.io.*;
import java.net.*;
import java.util.*;
import org.apache.http.*;
import org.apache.http.auth.*;
import org.apache.http.client.*;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.*;
import org.apache.http.client.utils.*;
import org.apache.http.impl.client.*;
public class Example {
public static void main(String[] args) throws Exception {
String server = "svn.xxx-xxx.de";
String path = "/upload.cgi";
Boolean https = true;
curl(server, path, https);
}
private static void curl(String server, String path, Boolean https)
throws URISyntaxException, IOException, ClientProtocolException {
CredentialsProvider credsProvider = new BasicCredentialsProvider();
credsProvider.setCredentials(
new AuthScope(server, (https ? 443:80)),
new UsernamePasswordCredentials("username", "password")
);
CloseableHttpClient httpclient = HttpClients
.custom()
.setDefaultCredentialsProvider(credsProvider)
.build();
URI uri = new URIBuilder()
.setScheme(https ? "https":"http")
.setHost(server)
.setPath(path)
.build();
try {
HttpPost httppost = new HttpPost(uri);
List<NameValuePair> formparams = new ArrayList<NameValuePair>();
formparams.add(new FileNameValuePair("access", new File("./svnaccess.txt")));
UrlEncodedFormEntity entity = new UrlEncodedFormEntity(formparams, Consts.UTF_8);
httppost.setEntity(entity);
CloseableHttpResponse response = httpclient.execute(httppost);
System.out.println(httppost.getRequestLine());
try {
System.out.println("----------------------------------------");
System.out.println(response.getStatusLine());
} finally {
response.close();
}
} finally {
httpclient.close();
}
}
}
FileNameValuePair.java
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
public class FileNameValuePair implements org.apache.http.NameValuePair
{
private String name;
private File file;
public FileNameValuePair(String name, File file)
{
this.name = name;
this.file = file;
}
public String getName() {
return name;
}
public String getValue() {
String everything = "";
try(BufferedReader br = new BufferedReader(new FileReader(file))) {
StringBuilder sb = new StringBuilder();
String line = br.readLine();
while (line != null) {
sb.append(line);
sb.append(System.lineSeparator());
line = br.readLine();
}
everything = sb.toString();
} catch (IOException e) {
e.printStackTrace();
}
return everything;
}
}
Solved it.
The #-argument indicates the upload of a file, rather than its contents.
Changed code:
MultipartEntityBuilder builder = MultipartEntityBuilder.create();
builder.addBinaryBody("access", new File("./svnaccess.txt"));
HttpEntity entity = builder.build();
httppost.setEntity(entity);
Thanks for pointing me in the right direction!

Sending Json POST to server using name value pair

I am sending Json Post request to server to through url: http://www.xyz.com/login
request structure:
{"requestdata":{"password":"abc","devicetype":"phone","username":"amrit#pqr.com","locale":"in"},"requestcode":10}
Code Snapshot:
MainActivity:
// Building post parameters
// key and value pair
List<NameValuePair> nameValuePair = new ArrayList<NameValuePair>();
nameValuePair.add(new BasicNameValuePair("requestcode", "10"));
nameValuePair.add(new BasicNameValuePair("devicetype", "phone"));
nameValuePair.add(new BasicNameValuePair("locale", "in"));
nameValuePair.add(new BasicNameValuePair("username", "amrit#pqr.com"));
nameValuePair.add(new BasicNameValuePair("password", "abc"));
RestPost post = new RestPost(loginUrl, nameValuePair);
String Response = post.postData();
Log.i("Response:", Response);
RestPost class
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.List;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.StatusLine;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import android.util.Log;
public class RestPost {
String url;
List<NameValuePair> nameValuePairs;
public RestPost(String str, List<NameValuePair> params) {
this.url = str;
this.nameValuePairs = params;
}
public String postData() {
HttpClient httpclient = new DefaultHttpClient();
HttpPost httppost = new HttpPost(this.url);
StringBuilder builder = new StringBuilder();
try {
httppost.setEntity(new UrlEncodedFormEntity(this.nameValuePairs));
HttpResponse response = httpclient.execute(httppost);
StatusLine statusLine = response.getStatusLine();
int statusCode = statusLine.getStatusCode();
Log.d("RestClient", "Status Code : " + statusCode);
HttpEntity entity = response.getEntity();
InputStream content = entity.getContent();
BufferedReader reader = new BufferedReader(new InputStreamReader(
content));
String line;
while ((line = reader.readLine()) != null) {
builder.append(line);
}
} catch (ClientProtocolException e) {
// TODO Auto-generated catch block
} catch (IOException e) {
// TODO Auto-generated catch block
}
return builder.toString();
}
}
But I'm not getting appropriate response, could anyone help me in sending appropriate format for getting server response. Thanks in advance.
Response which I'm getting:
{"error":{"resultCode":"400","status":"Invalid Request format"}}
You are currently sending the JSON in the form of
{
"requestcode": "10",
"devicetype": "phone",
"locale": "in",
"username": "amrit#pqr.com",
"password": "abc"
}
Which isn't the form the server is asking for. Try creating a string of the JSON you want to send. Then use:
httppost.setEntity(new StringEntity(jsonString, "UTF8"));
httppost.setHeader("Content-type", "application/json");
To send the string to the server.
I'm using AndroidHttpClient to post the request
AndroidHttpClient httpClient = AndroidHttpClient.newInstance("User Agent");
URL urlObj = new URL(url);
HttpHost host = new HttpHost(urlObj.getHost(), urlObj.getPort(), urlObj.getProtocol());
AuthScope scope = new AuthScope(urlObj.getHost(), urlObj.getPort());
HttpContext credContext = new BasicHttpContext();
HttpPost httpPost = new HttpPost (url);
httpPost.setEntity(new UrlEncodedFormEntity(nameValuePairsArrayList));
// Execute post request and get http response
HttpResponse httpResponse = httpClient.execute(host, httpPost, credContext);
httpClient.close();
This works perfectly for me.
AndroidHttpClient http = AndroidHttpClient.new Instance("hai");

JAVA Http POST request in UTF-8

My J2EE application is able to receive POST request from a JSP page, no problem about that.
But if I use another java application to send a POST request, the parameter received is not an UTF-8 string.
Here there is my code:
URL url = new URL("http://localhost:8080/ITUNLPWebInterface/SimpleApi");
HttpURLConnection cox = (HttpURLConnection) url.openConnection();
cox.setDoInput(true);
cox.setDoOutput(true);
cox.setRequestMethod("POST");
cox.setRequestProperty("Accept-Charset", "UTF-8");
cox.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
cox.setRequestProperty("charset", "UTF-8");
DataOutputStream dos = new DataOutputStream(cox.getOutputStream());
String query = "tool=ner&input=şaşaşa";
dos.writeBytes(query);
dos.close();
Am I doing something wrong?
Thanks for your reply
this work!!!.
package com.erenerdogan.utils;
import com.erenerdogan.webservice.ServiceInterface;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.params.HttpConnectionParams;
import org.apache.http.params.HttpParams;
import org.apache.http.util.EntityUtils;
/**
*
* #author erenerdogan
*/
public class WebService
{
private String server;
public WebService(String server) {
this.server = server;
}
private HttpPost createPostRequest(String method, Map<String, String> paramPairs){
// Creating HTTP Post
HttpPost httpPost = new HttpPost(server + "/" + method);
// Building post parameters
List<NameValuePair> nameValuePair = new ArrayList<NameValuePair>(paramPairs.size());
for (String key : paramPairs.keySet()){
nameValuePair.add(new BasicNameValuePair(key, paramPairs.get(key)));
System.out.println("Key : "+ key + " - Value : "+ paramPairs.get(key) );
}
// Url Encoding the POST parameters
try {
httpPost.setEntity(new UrlEncodedFormEntity(nameValuePair,"UTF-8"));
} catch (UnsupportedEncodingException e) {
// writing error to Log
e.printStackTrace();
}
return httpPost;
}
public String callServer(String method, Map<String, String> paramPairs) throws ClientProtocolException, IOException{
// Creating HTTP client
HttpClient httpClient = new DefaultHttpClient();
HttpParams httpParameters = httpClient.getParams();
HttpConnectionParams.setConnectionTimeout(httpParameters, 10 * 1000);
HttpConnectionParams.setSoTimeout(httpParameters, 3 * 1000);
HttpResponse httpResponse = httpClient.execute(createPostRequest(method, paramPairs));
HttpEntity httpEntity = httpResponse.getEntity();
String xml = EntityUtils.toString(httpEntity);
return xml;
}
}
The docs for DataOutputStream.writeBytes(String) says
Writes out the string to the underlying output stream as a sequence of bytes. Each character in the string is written out, in sequence, by discarding its high eight bits. If no exception is thrown, the counter written is incremented by the length of s.
Instead use cox.getOutputStream().write(query.getBytes("UTF-8"));
DataOutputStream is redundant here.
try this
HttpClient client = new DefaultHttpClient();
HttpPost port = new HttpPost("http://localhost:8080/ITUNLPWebInterface/SimpleApi");
List<NameValuePair> parameters = new ArrayList<NameValuePair>(3);
parameters.add(new BasicNameValuePair("tool", "ner"));
parameters.add(new BasicNameValuePair("input", "şaşaşa"));
//post.setEntity(new UrlEncodedFormEntity(params, "UTF-8"));
post.setEntity(new UrlEncodedFormEntity(params, "ISO-8859-3")); //try this one
HttpResponse resp = client.execute(post);
https://en.wikipedia.org/wiki/ISO/IEC_8859-3 seem to support your spechial character ş
It works form me:
connection = (HttpURLConnection) url.openConnection();
...
byte[] data = message.getBytes("UTF-8");
...
DataOutputStream wr = new DataOutputStream(
connection.getOutputStream());
wr.write(data);
wr.close();
a) "application/x-www-form-urlencoded" doesn't have a charset parameter; it's essentially limited to ASCII
b) to send non-ASCII characters, you need to encode them in UTF-8 (not the client's default encoding) and percent-escape them; see http://www.w3.org/TR/2014/REC-html5-20141028/forms.html#application/x-www-form-urlencoded-encoding-algorithm for the details.
base on HttpClient's Example "FluentRequests.java":
Content content = Request.Post("http://localhost:8080/ITUNLPWebInterface/SimpleApi")
.body(new UrlEncodedFormEntity(
Form.form()
.add("tool", "ner")
.add("input", "şaşaşa")
.build(), "UTF-8"))
.execute().returnContent();
System.out.println(content);

Apache Http Digest Authentication using Java

I am currently working on a Java project and I can't get the http digest authentication working. I tried using the Apache website, but it didn't help. I have a site that requires HTTP digest authentication.
DefaultHttpClient httpclient = new DefaultHttpClient();
String hostUrl = "http://somewebsite.com";
String postUrl = "http://somewebsite.com/request";
HttpPost httpPost = new HttpPost(postUrl);
String username = "hello";
String password = "world";
HttpHost targetHost = new HttpHost(hostUrl);
httpclient.getCredentialsProvider().setCredentials(
new AuthScope(hostUrl, AuthScope.ANY_PORT),
new UsernamePasswordCredentials(username, password));
AuthCache authCache = new BasicAuthCache();
DigestScheme digestAuth = new DigestScheme();
digestAuth.overrideParamter("realm", "some realm");
digestAuth.overrideParamter("nonce", "whatever");
authCache.put(targetHost, digestAuth);
BasicHttpContext localcontext = new BasicHttpContext();
localcontext.setAttribute(ClientContext.AUTH_CACHE, authCache);
// List<NameValuePair> nvps = new ArrayList<NameValuePair>();
// nvps.add(new BasicNameValuePair("username", "shirwa99#gmail.com"));
// nvps.add(new BasicNameValuePair("password", "example"));
// httpPost.setEntity(new UrlEncodedFormEntity(nvps));
HttpResponse response2 = httpclient.execute(httpPost);
This code works for me pretty well:
protected static void downloadDigest(URL url, FileOutputStream fos)
throws IOException {
HttpHost targetHost = new HttpHost(url.getHost(), url.getPort(), url.getProtocol());
CloseableHttpClient httpClient = HttpClients.createDefault();
HttpClientContext context = HttpClientContext.create();
String credential = url.getUserInfo();
if (credential != null) {
String user = credential.split(":")[0];
String password = credential.split(":")[1];
CredentialsProvider credsProvider = new BasicCredentialsProvider();
credsProvider.setCredentials(AuthScope.ANY,
new UsernamePasswordCredentials(user, password));
AuthCache authCache = new BasicAuthCache();
DigestScheme digestScheme = new DigestScheme();
authCache.put(targetHost, digestScheme);
context.setCredentialsProvider(credsProvider);
context.setAuthCache(authCache);
}
HttpGet httpget = new HttpGet(url.getPath());
CloseableHttpResponse response = httpClient.execute(targetHost, httpget, context);
try {
ReadableByteChannel rbc = Channels.newChannel(response.getEntity().getContent());
fos.getChannel().transferFrom(rbc, 0, Long.MAX_VALUE);
} finally {
response.close();
}
}
try this code from apache httpClient 4.3.3
final HttpHost targetHost = new HttpHost("localhost", 8080, "http");
final CredentialsProvider credsProvider = new BasicCredentialsProvider();
credsProvider.setCredentials(AuthScope.ANY,
new UsernamePasswordCredentials(user, password));
final AuthCache authCache = new BasicAuthCache();
DigestScheme digestAuth = new DigestScheme();
digestAuth.overrideParamter("realm", "some-realm");
digestAuth.overrideParamter("nonce", "whatever");
authCache.put(targetHost, digestAuth);
// Add AuthCache to the execution context
HttpClientContext context = HttpClientContext.create();
context.setAuthCache(authCache);
HttpGet httpget = new HttpGet("/");
CloseableHttpResponse response = httpclient.execute(targetHost , httpget, context );
Please can you give me the site which requires HTTP digest authentication?
Tipp: do not use HTTP Digest :) It is not secure at all. Over HTTPS it has not point.
If you must, below is a code that works with parsing the WWW-Authenticate header.
This is tested with the following dependency (i use gradle):
compile group: 'org.apache.httpcomponents', name: 'httpclient', version: '4.5.6'
The code:
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import org.apache.http.Header;
import org.apache.http.HttpHost;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.MalformedChallengeException;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.client.AuthCache;
import org.apache.http.client.CredentialsProvider;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.protocol.HttpClientContext;
import org.apache.http.impl.auth.DigestScheme;
import org.apache.http.impl.client.BasicAuthCache;
import org.apache.http.impl.client.BasicCredentialsProvider;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
public class DigestExample {
private final static String uri = "http://my.digest.based.auth.url.com";
private static HttpHost target;
public static void main(String[] args) throws IOException {
setup();
if (target == null) {
System.out.println("Setup was unsuccesfull");
return;
}
Header challengeHeader = getAuthChallengeHeader();
if (challengeHeader == null) {
System.out.println("Setup was unsuccesfull");
return;
}
// NOTE: challenge is reused for subsequent HTTP GET calls (typo corrected)
getWithDigestAuth(challengeHeader, "/", "/schema");
}
private static void setup() throws MalformedURLException {
URL url = new URL(uri);
target = new HttpHost(url.getHost(), url.getPort(), url.getProtocol());
}
private static Header getAuthChallengeHeader() {
try (CloseableHttpClient httpClient = HttpClients.createDefault()) {
CloseableHttpResponse response = httpClient.execute(new HttpGet(uri));
return response.getFirstHeader("WWW-Authenticate");
} catch (IOException e) {
e.printStackTrace();
return null;
}
}
private static void getWithDigestAuth(Header challengeHeader, String... requests)
throws IOException {
CredentialsProvider credsProvider = new BasicCredentialsProvider();
credsProvider.setCredentials(
new AuthScope(target.getHostName(), target.getPort()),
new UsernamePasswordCredentials("user", "pass"));
try (CloseableHttpClient httpclient = HttpClients.custom()
.setDefaultCredentialsProvider(credsProvider)
.build()) {
// Create AuthCache instance
AuthCache authCache = new BasicAuthCache();
// Generate DIGEST scheme object, initialize it and add it to the local
// auth cache
DigestScheme digestAuth = new DigestScheme();
digestAuth.processChallenge(challengeHeader);
authCache.put(target, digestAuth);
// Add AuthCache to the execution context
HttpClientContext localContext = HttpClientContext.create();
localContext.setAuthCache(authCache);
for (String request : requests) {
System.out.println("Executing request to target " + target + request);
try (CloseableHttpResponse response = httpclient
.execute(target, new HttpGet(request), localContext)) {
System.out.println("----------------------------------------");
System.out.println(response.getStatusLine());
System.out.println(EntityUtils.toString(response.getEntity()));
} catch (Exception e) {
System.out.println("Error while executing HTTP GET request");
e.printStackTrace();
}
}
} catch (MalformedChallengeException e) {
e.printStackTrace();
}
}
}
Try this code from Apache :
public static void main(String[] args) throws Exception {
HttpClient client = new HttpClient();
client.getState().setCredentials(
new AuthScope("myhost", 80, "myrealm"),
new UsernamePasswordCredentials("username", "password"));
// Suppose the site supports several authetication schemes: NTLM and Basic
// Basic authetication is considered inherently insecure. Hence, NTLM authentication
// is used per default
// This is to make HttpClient pick the Basic authentication scheme over NTLM & Digest
List authPrefs = new ArrayList(3);
authPrefs.add(AuthPolicy.BASIC);
authPrefs.add(AuthPolicy.NTLM);
authPrefs.add(AuthPolicy.DIGEST);
client.getParams().setParameter(AuthPolicy.AUTH_SCHEME_PRIORITY, authrefs);
GetMethod httpget = new GetMethod("http://myhost/protected/auth-required.html");
try {
int status = client.executeMethod(httpget);
// print the status and response
System.out.println(httpget.getStatusLine());
System.out.println(httpget.getResponseBodyAsString());
} finally {
// release any connection resources used by the method
httpget.releaseConnection();
}
}

How to add,set and get Header in request of HttpClient?

In my application I need to set the header in the request and I need to print the header value in the console...
So please give an example to do this the HttpClient or edit this in my code...
My Code is ,
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;
public class SimpleHttpPut {
public static void main(String[] args) {
HttpClient client = new DefaultHttpClient();
HttpPost post = new HttpPost("http://http://localhost:8089/CustomerChatSwing/JoinAction");
try {
List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(1);
nameValuePairs.add(new BasicNameValuePair("userId",
"123456789"));
post.setEntity(new UrlEncodedFormEntity(nameValuePairs));
HttpResponse response = client.execute(post);
BufferedReader rd = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));
String line = "";
while ((line = rd.readLine()) != null) {
System.out.println(line);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
Thanks in advance...
You can use HttpPost, there are methods to add Header to the Request.
DefaultHttpClient httpclient = new DefaultHttpClient();
String url = "http://localhost";
HttpPost httpPost = new HttpPost(url);
httpPost.addHeader("header-name" , "header-value");
HttpResponse response = httpclient.execute(httpPost);
On apache page: http://hc.apache.org/httpcomponents-client-ga/tutorial/html/fundamentals.html
You have something like this:
URIBuilder builder = new URIBuilder();
builder.setScheme("http").setHost("www.google.com").setPath("/search")
.setParameter("q", "httpclient")
.setParameter("btnG", "Google Search")
.setParameter("aq", "f")
.setParameter("oq", "");
URI uri = builder.build();
HttpGet httpget = new HttpGet(uri);
System.out.println(httpget.getURI());
You can test-drive this code exactly as is using the public GitHub API (don't go over the request limit):
public class App {
public static void main(String[] args) throws IOException {
CloseableHttpClient client = HttpClients.custom().build();
// (1) Use the new Builder API (from v4.3)
HttpUriRequest request = RequestBuilder.get()
.setUri("https://api.github.com")
// (2) Use the included enum
.setHeader(HttpHeaders.CONTENT_TYPE, "application/json")
// (3) Or your own
.setHeader("Your own very special header", "value")
.build();
CloseableHttpResponse response = client.execute(request);
// (4) How to read all headers with Java8
List<Header> httpHeaders = Arrays.asList(response.getAllHeaders());
httpHeaders.stream().forEach(System.out::println);
// close client and response
}
}

Categories

Resources