I want to add authentication header to my request. I'm using DefaultHttpClient from Apache httpclient 4.0.
I found that's done this way:
URI uri = new URI("http://www.bla.bla/folder/");
String host = uri.getHost();
int port = uri.getPort();
httpClient.getCredentialsProvider().setCredentials(
new AuthScope(host, port, AuthScope.ANY_SCHEME),
new UsernamePasswordCredentials("myuser", "mypassword")
);
This is executed and even with the debugger I see some credentials variable of the httpClient are set at the moment of doing the request. But I inspect web traffic with Charles and there's no authentication header.
Content of vars:
host: www.bla.bla
port: -1
Btw. I enabled Charles as a proxy to see the headers of the request, with:
HttpHost proxy = new HttpHost("127.0.0.1", 8888, "http");
httpParameters.setParameter(ConnRoutePNames.DEFAULT_PROXY, proxy);
I think that should not be altering my headers, would make no sense for webproxy... anyways if I disable the proxy stuff it also doesn't work (although I can't see the content of the header but I suppose it's the same reason).
Also tried using a request interceptor like described in Softhinker.com's post here: How can I send HTTP Basic Authentication headers in Android?
And I get exactly the same request, without authentification header.
What am I doing wrong?
Thanks in advance.
I got it working setting the header "manually" in the request.
request.setHeader(new BasicHeader("Authorization", authstring));
Related
I had a problem of HttpURLConnection Invalid HTTP method: PATCH and got a suggestion here in which the X-HTTP-Method-Override work around did not work out for me. So I tried
CloseableHttpClient httpClient = HttpClients.createDefault();
HttpPatch httpPatch = new HttpPatch(new URI("http://example.com"));
CloseableHttpResponse response = httpClient.execute(httpPatch);
where I am facing a challenge. My request is an HTTPS request and I have the url as https://192.168.1.1/foo/bar. I neither know the hostname of the ip 192.168.1.1 which is validated by CloseableHttpClient with the hostname on the certificate, nor want to perform a DNS look up to happen(not even in the known hosts).
Are there any feasibility to perform a PATCH request in my case?
I need to implement a series of HTTP requests in Java and decided to use Apaches HttpClient in version 4.3 (the most current one).
The problem is all these requests use a cookie for session management and I seem to be unable to find a way of accessing that cookie and passing it from request to request. My commands in using curl look something like:
# Login
curl -c cookies -d "UserName=username&Password=password" "https://example.com/Login"
# Upload a file
curl -b cookies -F fileUpload=#IMG_0013.JPG "https://example.com/File"
# Get results of server processing file
curl -b cookies "https://example.com/File/1234/Content"
They work perfectly. However with HttpClient it seems not to work. What I tried was:
URI serverAddress = new URI("https://example.com/");
URI loginUri = UriBuilder.fromUri(serverAddress).segment("Login").queryParam("UserName", "username")
.queryParam("Password", "password").build();
RequestConfig globalConfig = RequestConfig.custom().setCookieSpec(CookieSpecs.BEST_MATCH).build();
CookieStore cookieStore = new BasicCookieStore();
HttpClientContext context = HttpClientContext.create();
context.setCookieStore(cookieStore);
CloseableHttpClient httpClient = HttpClients.custom().setDefaultRequestConfig(globalConfig).setDefaultCookieStore(cookieStore).build();
HttpGet httpGet = new HttpGet(loginUri);
CloseableHttpResponse loginResponse = httpClient.execute(httpGet,context);
System.out.println(context.getCookieStore().getCookies());
The output of the last line is always an empty list. I think it should contain my Cookie, am I right?
Can someone give me a small example on how to handle the cookie using Apache HttpClient 4.3?
Thanks
Your code looks OK to me (other than not releasing resources, but I presume exception handling was omitted for brevity). The reason for cookie store being empty may be violation of the actual cookie policy (which is BEST_MATCH in your case) by the target server. So, cookies sent by the server get rejected as invalid. You can find out if that is the case (and other useful contextual details) by turning on context / wire logging as described here
Context
I have a desktop JAVA application I use to upload files (blobs) to a google app blobstore.
Everything works fine with a direct connection to the Internet but it doesn't when connecting through an HTTP proxy (Squid) with authentication.
I am using httpClient 4.2.3 and I don't get any error or response. It just gets stuck when calling httpClient.execute(post).
Code
I added these lines to handle the proxy authentication and it works well when using URL to get a page:
System.setProperty("http.proxyUser", username);
System.setProperty("http.proxyPassword", password);
I tried those as well:
Authenticator.setDefault(
new Authenticator() {
#Override
public PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication(
username, password.toCharArray());
}
}
);
And from now on this is the same code that works when not using a proxy.
First of all I download a page where I get the url to use to post a file to the blobstore:
URL url = new URL("http://www.example.com/get-upload-url.jsp");
String urlWhereToPost=IOUtils.toString(url.openStream());
DefaultHttpClient client = new DefaultHttpClient ();
Here we prepare the multipart post:
HttpPost post
= new HttpPost( urlWhereToPost.trim() );
MultipartEntity entity
= new MultipartEntity( HttpMultipartMode.BROWSER_COMPATIBLE);
entity.addPart( "key"
, new FileBody(new File(jpgFilePath)
, "image/jpeg" )
);
post.setEntity((HttpEntity)entity);
And it is when calling execute that nothing happens (and it never get's to the next instruction):
HttpResponse execute = client.execute( post );
Tests
I have been trying several things but nothing worked:
In the beginning I thought the problem was using POST because GET works fine using URL()
but I tried using HttpClient to execute a GET and it gets stuck as well.
I used Wireshark to check the packets send to the proxy and I saw that when using URL() Wireshark recognizes the calls to the proxy as requests to execute a GET from the proxy. But when using httpClient it looks like the request is not well built because Wireshark shows a packet but doesn't recognize the inner request.
Then I tried building the POST using HttpURLConnection and it gets through the proxy and I get the answer from the server but it looks like I am not building it well because appengine doesn't find the file I send (but this would be another question...).
Conclusion
Anyone with the same problem? Any idea?
Your proxy settings are for the Java system classes. Apache HttpClient is supposed to be configured in a different way.
This link may help: Proxy authentication
I have been using HTTPClient version 4.1.2 to try to access a REST over HTTP API that requires Basic Authentication. Here is client code:
DefaultHttpClient httpClient = new DefaultHttpClient(new ThreadSafeClientConnManager());
// Enable HTTP Basic Auth
httpClient.getCredentialsProvider().setCredentials(
new AuthScope(AuthScope.ANY_HOST, AuthScope.ANY_PORT),
new UsernamePasswordCredentials(this.username, this.password));
HttpHost proxy = new HttpHost(this.proxyURI.getHost(), this.proxyURI.getPort());
httpClient.getParams().setParameter(ConnRouteParams.DEFAULT_PROXY, proxy);
When I construct a POST request, like this:
HttpPost request = new HttpPost("http://my/url");
request.addHeader(new BasicHeader("Content-type", "application/atom+xml; type=entry")); // required by vendor
request.setEntity(new StringEntity("My content"));
HttpResponse response = client.execute(request);
I see in Charles Proxy that there are two requests being sent. One without the Authorization: Basic ... header and one with it. The first one fails with a 401, as you would expect, but the second goes through just fine with a 201.
Does anyone know why this happens? Thanks!
EDIT:
I should make clear that I have already looked at this question, but as you can see I set the AuthScope the same way and it didn't solve my problem. Also, I am creating a new HttpClient every time I made a request (though I use the same ConnectionManager), but even if I use the same HttpClient for multiple requests, the problem still persists.
EDIT 2:
So it looks like what #LastCoder was suggesting is the way to do. See this answer to another question. The problem stems from my lack of knowledge around the HTTP spec. What I'm looking to do is called "preemptive authentication" and the HttpClient docs mention it here. Thankfully, the answer linked to above is a much shorter and cleaner way to do it.
Rather than using .setCredentials() why don't you just encode USERNAME:PASSWORD and add the authentication header with .addHeader()
This means that your server/target endpoint is creating a new session for every client request. This forces every request of yours to go through a hand-shake, which means the clients first makes the call and realizes that it needs authorization, then it follows with the authorization. What you need to do is send the authorization preemptively as follows:
httpClient.getParams().setAuthenticationPreemptive(true);
Just to understand the process you may log your client request headers, to give you an idea of what your client is sending and receiving:
See if this works.
I am trying to send a GET request to the web server from the android device, the server is having digest authentication enabled, I am able to authenticate using following sort of code,
HttpHost host = new HttpHost(urlObj.getHost(), -1, null);
CredentialsProvider cp = new BasicCredentialsProvider();
cp.setCredentials(scope, creds);
HttpContext credContext = new BasicHttpContext();
credContext.setAttribute(ClientContext.CREDS_PROVIDER, cp);
Now my problem is every time when I call httpClient.execute() function it first send request without authentication header and then second time with proper headers. So is there any way I can instruct HttpClient to send authentication details by default?
One way is to store the last sent request but, I am also not able to get the last sent request. Any suggestion on this?
Thanks in advance.
You may use HttpURLConnection to save all the params you need. I use it and display my source code here.
url_connection is defined like that
private HttpURLConnection url_connection; // WebService Connection
url_connection= (HttpURLConnection) new URL(your_url_server).openConnection();
url_connection.setRequestMethod("POST");
url_connection.setDoInput(true);
url_connection.setDoOutput(true);
....