Java 8: Apache HttpClient failing authentication - java

I am attempting to use Apache HttpClient API to access Atlassian Confluence wiki pages.
Here is my code:
public class ConcfluenceTest{
public static void main(String[] args) {
String pageID = "107544635";
String hostName = "valid_hostname";
String hostScheme = "https";
String username = "verified_username";
String password = "verified_password";
int port = 443;
//set up the username/password authentication
BasicCredentialsProvider credsProvider = new BasicCredentialsProvider();
credsProvider.setCredentials(
new AuthScope(hostName, port, AuthScope.ANY_REALM, hostScheme),
new UsernamePasswordCredentials(username, password));
HttpClient client = HttpClientBuilder.create()
.setDefaultCredentialsProvider(credsProvider)
.build();
try {
HttpGet getRequest = new HttpGet("valid_url");
System.out.println(getRequest.toString());
HttpResponse response = client.execute(getRequest);
//Parse the response
BufferedReader rd = new BufferedReader(
new InputStreamReader(response.getEntity().getContent()));
StringBuffer result = new StringBuffer();
String line = "";
while ((line = rd.readLine()) != null) {
result.append(line);
}
System.out.println(result.toString());
} catch (UnsupportedEncodingException e) {
System.out.println(e.getStackTrace());
} catch (IOException e) {
System.out.println(e.getStackTrace());
}
}
}
When I attempt to execute this code, the printed response is the HTML of the Log In screen, which means that the authentication failed. This code does, however, return the correct response when I provide it with the URL to a page that is not restricted to registered users (i.e credentials aren't required). I also tried all permutations of port/scheme.
Can someone tell me what I am missing?

Afaik, if http-basic-auth is supported, something like
user:password#server:port/path
should work, too. You could see if that works with a browser.
If Confluence dosen't support basic auth, use firebug to find out the action of the login-form (eg. the path, something like /dologin.action), the method (POST) and the Names of the user/password fields.
With that information you can create a request like this:
HttpPost httpPost = new HttpPost(fullFormActionUrlWithServerAndPort);
List <NameValuePair> nvp = new ArrayList <NameValuePair>();
nvp.add(new BasicNameValuePair("name-of-the-user-field", "your-user-name"));
nvp.add(new BasicNameValuePair("name-of-the-pass-field", "your-password"));
httpPost.setEntity(new UrlEncodedFormEntity(nvp));

Related

GET request Tomcat Manager

I'm trying to remotely deploy application to Tomcat. To do that, I need to do the following GET request:
http://localhost:8080/manager/text/deploy?path=/client-001&war=file:C:/.DS/tmp/client-001.war
I do it from my Java code:
String url = "http://localhost:8080/manager/text/deploy?path=/client-001&war=file:C:/.DS/tmp/client-001.war";
HttpClient client = HttpClientBuilder.create().build();
HttpGet request;
try {
request = new HttpGet(url);
request.addHeader(BasicScheme.authenticate(
new UsernamePasswordCredentials("test", "test"),
"UTF-8", false));
HttpResponse response = client.execute(request);
BufferedReader rd = new BufferedReader(
new InputStreamReader(response.getEntity().getContent()));
StringBuffer result = new StringBuffer();
String line = "";
while ((line = rd.readLine()) != null) {
result.append(line);
}
System.err.println(result.toString());
} catch (Exception e){
e.printStackTrace();
}
but I get 403, even though I've passed my credentials.
What am I doing wrong?
So I found out what the problem was.
1) I didn't need to pass credentials to the Header, I just needed to change url from localhost:8080 to test:test#localhost:8080
2) My user test had role manager-gui, and for GET to work it needed the role manager-script

Trying setting session cookie using HttpClient

Help setting cookie to HttpClient
Created a program which logins to an external web service. However, to obtain vital information from
an HTTP GET, I am unable to pass in the cookie (generated from the login).
public class ClientHelper {
private final static String PROFILE_URL =
"http://externalservice/api/profile.json";
private final static String LOGIN_URL = "http://externalservice/api/login";
public static Cookie login(final String username, final String password) {
DefaultHttpClient client = new DefaultHttpClient();
HttpPost post = new HttpPost(LOGIN_URL);
HttpContext localContext = new BasicHttpContext();
client.getParams().setParameter("http.useragent", "Custom Browser");
client.getParams().setParameter(CoreProtocolPNames.PROTOCOL_VERSION,
HttpVersion.HTTP_1_1);
List<Cookie> cookies = null;
BasicClientCookie cookie = null;
try {
List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(3);
nameValuePairs.add(new BasicNameValuePair("user", username));
nameValuePairs.add(new BasicNameValuePair("passwd", password));
UrlEncodedFormEntity entity =
new UrlEncodedFormEntity(nameValuePairs, HTTP.UTF_8);
entity.setContentType("application/x-www-form-urlencoded");
post.setEntity(new UrlEncodedFormEntity(nameValuePairs));
HttpResponse response = client.execute(post, localContext);
cookies = client.getCookieStore().getCookies();
System.out.println(cookies.get(1));
cookie = new BasicClientCookie(cookies.get(1).getName(), cookies.get(1).getValue());
cookie.setVersion(cookies.get(1).getVersion());
cookie.setDomain(cookies.get(1).getDomain());
cookie.setExpiryDate(cookies.get(1).getExpiryDate());
cookie.setPath(cookies.get(1).getPath());
BufferedReader rd = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));
String line = "";
while ((line = rd.readLine()) != null) {
System.out.println(line);
}
}
catch (Throwable e) {
e.printStackTrace();
}
return cookie;
}
public static void getProfile(Cookie cookie) {
DefaultHttpClient client = new DefaultHttpClient();
HttpContext context = new BasicHttpContext();
CookieStore cookieStore = new BasicCookieStore();
cookieStore.addCookie(cookie);
client.setCookieStore(cookieStore);
context.setAttribute(ClientContext.COOKIE_STORE, cookieStore);
HttpGet get = new HttpGet(PROFILE_URL);
HttpResponse response;
try {
response = client.execute(get, context);
BufferedReader rd =
new BufferedReader(
new InputStreamReader(response.getEntity().getContent()));
String line = "";
while ((line = rd.readLine()) != null) {
System.out.println(line);
}
}
catch (ClientProtocolException e) {
e.printStackTrace();
}
catch (IOException e) {
e.printStackTrace();
}
}
}
App.java (class that uses ClientHelper):
public class App {
private static final String USER = "myusername";
private static final String PASSWD = "mypassword";
public static void main(String[] args) {
Cookie cookie = ClientHelper.login(USER, PASSWD);
ClientHelper.getProfile(cookie);
}
}
When I run App, I am able to login (I see the generated JSON) but the getProfile() method returns an empty JSON object:
{}
From the command line, using curl I am trying to emulate this:
curl -b Cookie.txt http://externalservice/api/profile.json
This actually works but not my Java program.
Try by executing this part of the code:
List<Cookie> cookies = client.getCookieStore().getCookies();
for (Cookie cookie : cookies) {
singleCookie = cookie;
}
After
HttpResponse response = client.execute(post, localContext);
After changing your code to get the cookies after the login request, you actually are getting all the cookies from the request.
I suspect the problem is that whatever Cookie it is at index 1 in the CookieStore isn't the one you need, and obviously since it's not throwing an IndexOutOfBounds exception when you do that, there's at least one other Cookie in there (at index 0). Return the list of cookies and send all of them with your profile request.
Taking your code, changing all those indexes from 1 to 0 and pointing at this simple PHP script shows that it is receiving then sending the cookies:
<?php
setcookie("TestCookie", "Some value");
print_r($_COOKIE);
?>
output:
[version: 0][name: TestCookie][value: Some+value][domain: www.mydomain.org][path: /][expiry: null]
Array
(
)
Array
(
[TestCookie] => Some value
)
I figured it out... I was creating two different HTTP clients instead of using the same one.
#Brian Roach & Raunak Agarwal thank you both very much for the help!
Here's the fix:
public static HttpClient login(final String username, final String password)
{
HttpClient client = new DefaultHttpClient();
HttpPost post = new HttpPost(LOGIN_URL);
client.getParams().setParameter("http.useragent", "Custom Browser");
client.getParams().setParameter(
CoreProtocolPNames.PROTOCOL_VERSION, HttpVersion.HTTP_1_1);
try
{
List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(3);
nameValuePairs.add(new BasicNameValuePair("user", username));
nameValuePairs.add(new BasicNameValuePair("passwd", password));
UrlEncodedFormEntity entity =
new UrlEncodedFormEntity(nameValuePairs, HTTP.UTF_8);
entity.setContentType("application/x-www-form-urlencoded");
post.setEntity(new UrlEncodedFormEntity(nameValuePairs));
HttpResponse response = client.execute(post);
BufferedReader reader =
new BufferedReader(
new InputStreamReader(response.getEntity().getContent()));
String line = "";
while ((line = reader.readLine()) != null)
{
System.out.println(line);
}
}
catch (Throwable e) { e.printStackTrace(); }
return client;
}
public static void getProfile(HttpClient client)
{
HttpGet get = new HttpGet(PROFILE_URL);
HttpResponse response;
try
{
response = client.execute(get);
BufferedReader reader =
new BufferedReader(
new InputStreamReader(response.getEntity().getContent()));
String line = "";
while ((line = reader.readLine()) != null)
{
System.out.println(line);
}
}
catch (ClientProtocolException e) { e.printStackTrace(); }
catch (IOException e) { e.printStackTrace(); }
}

Destroying or Closing HttpClient Android

I have a problem that I think it may relate to the HttpClient. I am logging into a website and grabbing data from it using JSoup. Everything works fine. Here is my issue, when I want to log into a different account, it displays the same data from the other account. Only when I kill the app is when I am able to login with different credentials. I think that my session with the website is still stored in the same HttpClient and won't let me log in again with a different account unless I logout. What would be the best way to fix this problem? Using HttpGet method to execute the logout script? Or is there a way to reset the HttpCLient. Thanks. Code:
public void parseDoc() {
new Thread(new Runnable() {
#Override
public void run() {
final HttpParams params = new BasicHttpParams();
HttpClientParams.setRedirecting(params, true);
httpclient = new DefaultHttpClient();
HttpPost httppost = new HttpPost(
"https://secure.groupfusion.net/processlogin.php");
String HTML = "";
try {
List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(
3);
nameValuePairs
.add(new BasicNameValuePair(
"referral_page",
"/modules/gradebook/ui/gradebook.phtml?type=student_view&jli=t&jli=t&jli=t&jli=t&jli=t&jli=t&printable=FALSE&portrait_or_landscape=portrait"));
nameValuePairs.add(new BasicNameValuePair("currDomain",
"beardenhs.knoxschools.org"));
nameValuePairs.add(new BasicNameValuePair("username",
username.getText().toString()));
nameValuePairs.add(new BasicNameValuePair("password",
password.getText().toString()));
httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
HttpResponse response = httpclient.execute(httppost);
HTML = EntityUtils.toString(response.getEntity());
Document doc = Jsoup.parse(HTML);
Element link = doc.select("a").first();
String linkHref = link.attr("href");
HttpGet request = new HttpGet();
try {
request.setURI(new URI(linkHref));
} catch (URISyntaxException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
response = httpclient.execute(request);
InputStream in = response.getEntity().getContent();
BufferedReader reader = new BufferedReader(
new InputStreamReader(in));
StringBuilder str = new StringBuilder();
String line = null;
while ((line = reader.readLine()) != null) {
str.append(line);
}
in.close();
HTML = str.toString();
doc = Jsoup.parse(HTML);
Elements divs = doc.getElementsByTag("tbody");
for (Element d : divs) {
if (i == 2) {
finishGrades();
break;
}
i++;
ggg = d.html();
}
} catch (ClientProtocolException e) {
} catch (IOException e) {
}
}
}).start();
}
You can call httppost.abort();
I ran into a similar problem, although I am using one instance of the HttpClient for the whole application (Singleton). So in that case, if you use preemptive authentication, you can simply do this for the application-wide client instance (e.g. if the user logs out):
public void logOut() {
// keep in mind, 'httpClient' is final and set once in the constructor (Singleton)
httpClient.getCredentialsProvider().clear();
httpClient.getCookieStore().clear(); // important
}
See also: HttpClient State Management
I would suggest setting "no-cache" header of httpclient to false and try. Not guaranteed solution.

Android 2.2 (level 8) httpclient.execute consistent timeout

I'm attempting to receive a response from a restful service, but receive a timeout. I am able to connect with the browser on my emulator, as I have configured an access point on the emulated device to pass through proxy (at work). Network seems to be fine. I've added:
<uses-permission android:name="android.permission.INTERNET" />
to the AndroidManifest.xml file.
The code is as follows:
public String getInputStreamFromUrl(String url) {
String content = null;
InputStream stream = null;
try {
HttpGet httpGet = new HttpGet(url);
HttpClient httpclient = new DefaultHttpClient();
// Execute HTTP Get Request
HttpResponse response = httpclient.execute(httpGet);
stream = response.getEntity().getContent();
BufferedReader rd = new BufferedReader(new InputStreamReader(stream), 4096);
String line;
StringBuilder sb = new StringBuilder();
while ((line = rd.readLine()) != null) {
sb.append(line);
}
rd.close();
content = sb.toString();
} catch (Exception e) {
content = e.getMessage();
}
return content;
I know I should return a stream, but for the sake of just displaying some string values in a TextView widget, will suffice, so I'm just using the string to experiment. It consistently hangs on .execute, no matter what URL is passed. I've passed valid IP's as well, with nothin' doin'.
I appreciate your help in advance.
Try this. Put it at the top of the class.
System.setProperty("http.proxyHost", <your proxy host name>);
System.setProperty("http.proxyPort", <your proxy port>);

Basic HTTP Authentication on Android Phones to Rails Server

I'm trying to connect to a Rails Application Server that requires authentication. I am using the Jakarta HTTP Client for Java on a Desktop application and it works 100%. But when the exact same code is executed on the Android Emulator I get an IOException.
Here is the code, and if anyone could help me figure out why it throws the IOException that would be greatly appreciated!
private boolean login()
{
String username, password;
DefaultHttpClient client;
AuthScope scope;
Credentials myCredentials;
CredentialsProvider provider;
HttpEntity entity;
String line;
BufferedReader reader;
InputStream instream;
//Declare & Create the HTTP Client
client = new DefaultHttpClient();
//Create our AuthScope
scope = new AuthScope("10.19.9.33", 3000);
username = "admin"
password = "pass"
//Set Credentials
myCredentials = new UsernamePasswordCredentials( username, password );
//Set Provider
provider = new BasicCredentialsProvider();
provider.setCredentials(scope, myCredentials);
//Set Credentials
client.setCredentialsProvider( provider );
String url = "http://10.19.9.33:3000/users/show/2";
HttpGet get;
//Tell where to get
get = new HttpGet( url );
HttpResponse response;
try
{
response = client.execute( get );
entity = response.getEntity();
/* Check to see if it exists */
if( entity != null )
{
instream = entity.getContent();
try {
reader = new BufferedReader(new InputStreamReader(instream));
line = reader.readLine();
if( line.equals( "HTTP Basic: Access denied.") )
return false;
while ( line != null )
{
// do something useful with the response
System.out.println(line);
line = reader.readLine();
}
return true;
}
catch (IOException ex)
{
// In case of an IOException the connection will be released
// back to the connection manager automatically
throw ex;
}
catch (RuntimeException ex)
{
// In case of an unexpected exception you may want to abort
// the HTTP request in order to shut down the underlying
// connection and release it back to the connection manager.
get.abort();
throw ex;
}
finally
{
// Closing the input stream will trigger connection release
instream.close();
}
}
}
catch( ClientProtocolException cp_ex )
{
}
catch( IOException io_ex )
{
}
return false;
}
The reason it kept triggering the IOException was because the Manifest file didn't give the Application rights to the internet
<uses-permission android:name="android.permission.INTERNET"></uses-permission>
I'm using HttpPost for this kind of task, and never had any problem:
[...]
DefaultHttpClient client = new DefaultHttpClient();
HttpPost httppost = new HttpPost(LOGIN_SERVLET_URI);
List<BasicNameValuePair> params = new ArrayList<BasicNameValuePair>();
params.add(new BasicNameValuePair("userName", userName));
params.add(new BasicNameValuePair("password", password));
UrlEncodedFormEntity p_entity = new UrlEncodedFormEntity(params, HTTP.UTF_8);
httppost.setEntity(p_entity);
HttpResponse response = client.execute(httppost);
HttpEntity responseEntity = response.getEntity();
[...]
maybe this helps you out

Categories

Resources