Can't access cookie store from android - android

I'm trying this
HttpClient httpClient = new DefaultHttpClient();
CookieStore cookieStore = httpClient.getCookieStore();
List<Cookie> cookies = cookieStore.getCookies();
But I can't access the getCookieStore(). It just doesn't exist on the httpClient. The ony gets that are available are
httpClient.getClass()
httpClient.getConnectionManager()
httpClient.getParams()
nothing else.
I increased my api level but that still didn't work. Not sure what I need to do to access the cookies that are returned from a client?

I changed HttpClient to DefaultHttpClient. i.e. I went from
HttpClient httpClient = new DefaultHttpClient()
to
DefaultHttpClient httpClient = new DefaultHttpClient();

Related

Django: resetting password without a CSRF token

I have a Django website that manages Users. Using the built-in functionality, users can request a password reset from the website and that works great. I have implemented it according to this tutorial so I am using the built-in password reset functionality.
I have an Android app from which users should also be able to request a password reset. The problem is that I do not have a CSRF token in the application, and the the built-in password_reset method has the #csrf_protect decorator. This means that I cannot access it without a CSRF token and I also can't modify it with the #csrf_exempt decorator.
So the next idea is to create a function, which generates a CSRF token, stores it in the request and redirects to the correct URL which sends the reset email. The problem is that according to this, django does not allow to pass POST parameters further in a redirect.
Therefore my question is how can I request a password reset in Django without a CSRF token? Alternatively, what is the correct way to request this from an application?
I found a solution myself. Please feel free to post any alternative solutions. One that doesn't require two separate requests would be particularly great.
If you look at the password_reset method, you can see that it only tries to process the request as a reset request if the request method is POST. Otherwise it just returns a TemplateResponse containing a form. This also contains the CSRF token as a cookie.
So first, I send a GET request to http://myaddress.com/user/password/reset/ and extract the CSRF cookie from the response. Then I send a POST request containing the cookie, the email address and 2 headers (see below).
This is the code I've implemented to achieve this from Android (trimmed):
String url = "http://myaddress.com/user/password/reset/";
GET Request:
HttpClient httpClient = new DefaultHttpClient();
HttpGet httpGet = new HttpGet(url);
CookieStore cookieStore = new BasicCookieStore();
HttpContext localContext = new BasicHttpContext();
localContext.setAttribute(ClientContext.COOKIE_STORE, cookieStore);
HttpResponse httpResponse = httpClient.execute(httpGet, localContext);
Cookie csrfCookie = null;
for (Cookie cookie : cookieStore.getCookies()) {
if (cookie.getName() == "csrftoken") {
csrfCookie = cookie;
break;
}
}
if (csrfCookie == null) {
throw new NullPointerException("CSRF cookie not found!");
}
return csrfCookie;
Note that you want the CookieStore from org.apache.http.client.
POST Request:
HttpClient httpClient = new DefaultHttpClient();
HttpContext localContext = new BasicHttpContext();
HttpPost httpPost = new HttpPost(url);
// Prepare the cookie store to receive cookies.
CookieStore cookieStore = new BasicCookieStore();
cookieStore.addCookie(csrfCookie);
httpPost.setHeader("Referer", url);
httpPost.setHeader("X-CSRFToken", csrfCookie.getValue());
localContext.setAttribute(ClientContext.COOKIE_STORE, cookieStore);
MultipartEntityBuilder builder = MultipartEntityBuilder.create();
builder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);
builder.addTextBody("email", emailAddressToReset);
httpPost.setEntity(builder.build());
HttpResponse httpResponse = httpClient.execute(httpPost, localContext);
if (httpResponse.getStatusLine().getStatusCode() != 200) {
throw new Exception("Could not reset password!");
}
Toast.makeText(context, "Password reset requested! Please check your email inbox!", Toast.LENGTH_LONG).show();

HttpContext not holding cookies

I'm trying to use cookies to hold my session on my Android app, but it seems I'm getting something wrong, because I never receive the expected response from my server.
At first I have a login routine that runs as expected and return all expected data.
My login request:
HttpContext httpContext = new BasicHttpContext();
HttpResponse response;
HttpClient client = new DefaultHttpClient();
String url = context.getString(R.string.url_login);
HttpPost connection = new HttpPost(url);
connection.setHeader("Content-Type","application/x-www-form-urlencoded");
List<NameValuePair> nameValuePair = new ArrayList<NameValuePair>(2);
nameValuePair.add(new BasicNameValuePair(PARAM_LOGIN,params[0]));
nameValuePair.add(new BasicNameValuePair(PARAM_PASSWORD,params[1]));
connection.setEntity(new UrlEncodedFormEntity(nameValuePair,"UTF-8"));
response = client.execute(connection,httpContext);
data = EntityUtils.toString(response.getEntity());
After I've my response I just make what ever I need with the data and then things start to fall a part. Because now I'm just trying to call my server in the same AsyncTask to test if my cookies got properly saved on my HttpContext.
At first I've just called my URL without any change, just reusing my current HttpContext:
HttpPost httpPost = new HttpPost(context.getString(R.string.url_cookie_test));
HttpResponse response = client.execute(httpPost, httpContext);
Since this test fails I tested to add my cookie value on my HttpPost header:
httpPost.addHeader(context.getString(R.string.domain),PHPSESSID+"="+cookieID+";");
Then I tried creating a new HttpContext and force the COOKIE_STORE:
CookieStore cookieStore = new BasicCookieStore();
BasicClientCookie cookie = new BasicClientCookie(PHPSESSID, cookieID);
cookieStore.addCookie(cookie);
HttpContext localContext = new BasicHttpContext();
localContext.setAttribute(ClientContext.COOKIE_STORE, cookieStore);
HttpResponse response;
HttpClient client = new DefaultHttpClient();
HttpPost httpPost = new HttpPost(context.getString(R.string.url_cookie_test));
response = client.execute(connection,localContext);
All fails, and I've already confirmed that when I first receive my login response I got the data expected from the cookies as can see below:
List<Cookie> cookies = ((AbstractHttpClient) client).getCookieStore().getCookies();
for (Cookie cookie: cookies){
Log.i("Cookie Value",cookie.toString());
/*
Prints:[[version: 0][name: PHPSESSID][value: 2ebbr87lsd9077m79n842hdgl3][domain: mydomain.org][path: /][expiry: null]]
*/
}
I've already searched on StackOverflow and I've found a ton of solutions that doesn't really worked for me, will share all solutions I've already tried:
Android: Using Cookies in HTTP Post request
HttpPost request with cookies
Sending cookie with http post android
Apache HttpClient 4.0.3 - how do I set cookie with sessionID for POST request
As I told you, here you are this piece of code in order to make httpPost to a server developed in Spring MVC, with an API REST. Please, consider to build your request on this way:
Please, pay attention to the comments. You should adapt it to your case ;). You can also enclose this code into a method or whatever you prefer.
try {
HttpClient httpclient = new DefaultHttpClient();
HttpPost httppost = new HttpPost("yourPath");
//NameValuePairs is build with the params for your request
httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
httppost.setHeader("Content-Type",
"application/x-www-form-urlencoded");
CookieStore cookieStore = new BasicCookieStore();
//cookie is a variable that I stored in my shared preferences.
//You have to send in it every request
//In your case, JSESSIONID should change, because it's for Java.
//Maybe it could be "PHPSESSID"
BasicClientCookie c = new BasicClientCookie("JSESSIONID", cookie);
//JSESSIONID: same comment as before.
httppost.setHeader("Cookie", "JSESSIONID="+cookie);
cookieStore.addCookie(c);
((AbstractHttpClient)httpclient).setCookieStore(cookieStore);
HttpResponse response = httpclient.execute(httppost);
HttpEntity entity = response.getEntity();
is = entity.getContent();
} catch (Exception e) {
Log.e("log_tag", "Error in http connection" + e.toString());
}
I hope this helps!! It was hard to find it among "old" projects :)

Android How to save cookies on sdcard using HttpClient

I need to know a way to store my HttpClient cookieStore on a txt file as a string and how to re-use those and make a new httpConnection.
httpclient=new DefaultHttpClient();
cookieStore = new BasicCookieStore();
localContext= new BasicHttpContext();
localContext.setAttribute(ClientContext.COOKIE_STORE, cookieStore);

NTLM authentication in Android app

I'm using JCIFS library found here to use NTLM authentication in my android app.The app worked fine when it just went to a site and parsed an xml, but now that I added the NTLM auth it doesn't seem to be working. Can anyone tell from this snippet of code if where the problem is between the httpclient and the inputstream?
DefaultHttpClient client = new DefaultHttpClient();
client.getAuthSchemes().register("ntlm", new NTLMSchemeFactory());
client.getCredentialsProvider().setCredentials(new AuthScope("http://www.musowls.org",80),
new NTCredentials(username, password, null, "musschool"));
HttpGet request = new HttpGet("http://www.musowls.org/assignments/assignmentsbystudentxml.aspx");
HttpResponse resp = client.execute(request);
HttpEntity entity = resp.getEntity();
InputStream inputStream = entity.getContent();
Try below code it may be help you.
DefaultHttpClient httpclient = new DefaultHttpClient();
httpclient.getAuthSchemes().register("ntlm", new NTLMSchemeFactory());
NTCredentials creds = new NTCredentials("user_name", "password", "", "http://www.musowls.org/");
httpclient.getCredentialsProvider().setCredentials(AuthScope.ANY, creds);
HttpConnectionParams.setConnectionTimeout(httpclient.getParams(), 5000);
HttpPost httppost = new HttpPost("http://www.musowls.org/assignments/assignmentsbystudentxml.aspx");
httppost.getParams().setBooleanParameter(CoreProtocolPNames.USE_EXPECT_CONTINUE, false);
HttpResponse response = httpclient.execute(httppost); // ERROR HAPPENS HERE
responseXML = EntityUtils.toString(response.getEntity());
Log.d("Responce", responseXML);
1) Download JCIFS from here: http://jcifs.samba.org/
2) Follow the instructions here: http://hc.apache.org/httpcomponents-client-ga/ntlm.html
Been stuck on this problem for way too long.
Check out the answer in this thread to use OkHttp3 for NTLM Authenticated calls:
https://stackoverflow.com/a/42114591/3708094

How to use HttpClient using Post method?

How to use HttpClient using Post method ?
See a docs on DefaultHttpClient class and HttpPost class
HttpClient client = new DefaultHttpClient();
HttpPost post = new HttpPost("http://your.site/your/service");
// set some headers if needed
post.addHeader(....);
// and an eclosed entity to send
post.setEntity(....);
// send a request and get response (if needed)
InputStream responseStream = client.execute(post).getEntity().getContent();
here you can get an good example Executing a HTTP POST Request with HttpClient

Categories

Resources