I trying to get authenticated from a website. I am using AsyncHttpClient
. Heres the code that I am trying.
Here is my code,
public class LoginActivity extends Activity {
String tag = "LoginActivity";
Button requestBtn;
AsyncHttpClient httpClient = new AsyncHttpClient();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login);
requestBtn = (Button) findViewById(R.id.upload_file);
PersistentCookieStore myCookieStore = new PersistentCookieStore(this);
httpClient.setCookieStore(myCookieStore);
httpClient.setBasicAuth(ApplicationConstants.userName,
ApplicationConstants.password, new AuthScope(
"http://*.*.*.*:8080/someUrl", 8080,
AuthScope.ANY_REALM));
requestBtn.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
httpClient.get("http://*.*.*.*:8080/someurl",new AsyncHttpResponseHandler() {
@Override
public void onSuccess(String response) {
System.out.println(response);
Log.d("Sucessful upload","Onsucess" + response);
}
@Override
public void onFailure(Throwable arg0,String arg1) {
Log.d("LoginActivity",arg0.toString());
arg0.printStackTrace();
super.onFailure(arg0, arg1);
}
});
}
}
});
}
}
I get an exception when I tap on the button. It says authentication failed Exception Logcat:
02-27 16:02:42.930: D/LoginActivity(8869): org.apache.http.client.HttpResponseException: Unauthorized
02-27 16:02:42.930: W/System.err(8869): org.apache.http.client.HttpResponseException: Unauthorized
02-27 16:02:42.930: W/System.err(8869): at com.loopj.android.http.AsyncHttpResponseHandler.sendResponseMessage(AsyncHttpResponseHandler.java:235)
02-27 16:02:42.930: W/System.err(8869): at com.loopj.android.http.AsyncHttpRequest.makeRequest(AsyncHttpRequest.java:79)
02-27 16:02:42.930: W/System.err(8869): at com.loopj.android.http.AsyncHttpRequest.makeRequestWithRetries(AsyncHttpRequest.java:95)
02-27 16:02:42.930: W/System.err(8869): at com.loopj.android.http.AsyncHttpRequest.run(AsyncHttpRequest.java:57)
02-27 16:02:42.930: W/System.err(8869): at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:442)
02-27 16:02:42.930: W/System.err(8869): at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305)
02-27 16:02:42.930: W/System.err(8869): at java.util.concurrent.FutureTask.run(FutureTask.java:137)
02-27 16:02:42.940: W/System.err(8869): at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076)
02-27 16:02:42.940: W/System.err(8869): at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:569)
02-27 16:02:42.940: W/System.err(8869): at java.lang.Thread.run(Thread.java:856)
What wrong I am doing? The URL I am using is correct.
I guess you can resolve this issue by explicitly adding the header which handle Basic Auth.
Also don't forget to override the "onComplete" method as well if you want to know what was the server response. Because in case of exception it might not go through "onSuccess" and "onFailure"..
From Basic Authentication with Android:
Android is shipping with Apache's HttpClient 4.0 Beta2, which has a pitfall, when it comes to Basic Authentication.
When you search for HttpClient and Basic Authentication, Google will most definitely send you to the official documentation of HttpClient 3.x, which shows you, how to do Basic Authentication in a preemptive way. That means, sending the client's credentials with every request, instead of waiting for a 401 Unauthorized response and only then sending the credentials. That's probably what you want to in the first place, because it saves your client a request.
This sample code won't compile with HttpClient version 4. The method called setAuthenticationPreemptive is missing. The problem is, if you omit this very method call, the code still works, but the authentication is not preemptive. We missed this little detail and only noticed after a while, that every request was preceded by a 401 Unauthorized request/response cycle. That doubled the amount of requests we served.
Now check the implementation of AsyncHttpClient:
So I think loopj might also run into the problem of using the old HttpClient 3.x way of doing Basic Authentication. It does work, but it's not preemptive.
A straightforward solution will be download the source code of loopj and modify its source and use the modified version.
Modification in code would be:
instead of
I came up with another solution, because I was having issues with in-between-proxies that didn't like how the Authorization header was built by using the above proposed solution and also the default (buggy)
setBasicAuth(username, password)
implementation of AsyncHttpClient.So I added the header myself, doing the BASE64 username/password encoding myself, but using the
addHeader()
method inherited from the parent client implementation.It works now.
I hope this helps somebody.