android Django rest API,authentication - android

A friend have a Rest API with Django, and Im trying to make and android app for it, but I having problems with the authentication.
First i get the CSRF token, just making a get call and taking the value.
public String getCFSRToken() throws Exception{
String csrftokenValue="";
httpClient.execute(new HttpGet(urlBasic));
cookieStore = httpClient.getCookieStore();
List <Cookie> cookies = cookieStore.getCookies();
for (Cookie cookie: cookies) {
Log.v("csrftoken",cookie.getName());
if ( cookie.getName().compareTo("csrftoken")==0) {
csrftokenValue = cookie.getValue();
}
}
return csrftokenValue;
}
Then I try to make the authentication:
public void login3() throws Exception{
String urlLogin ="/login";
String url = urlBasic+urlLogin;
String username = "jesus.m.martinez.garcia";
String password = "lolofree";
String userpass = username +":"+password;
HttpPost post = new HttpPost(url);
// List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(2);
// nameValuePairs.add(new BasicNameValuePair("username", username));
// nameValuePairs.add(new BasicNameValuePair("password", password));
// post.setEntity(new UrlEncodedFormEntity(nameValuePairs));
String basicAuth = "Basic " + new String(Base64.encode(userpass.getBytes(),Base64.NO_WRAP ));
post.addHeader("Authorization", basicAuth);
post.addHeader("X-CSRFToken", getCFSRToken());
HttpResponse response = httpClient.execute(post);
CookieStore as = httpClient.getCookieStore();
BufferedReader rd = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));
String line = "";
String pagina="";
while ((line = rd.readLine()) != null) {
pagina= pagina + "\n"+line;
}
System.out.println(pagina);
}
If I don't add the CSRF header I receive always a 403 Forbidden, so I suppose that part is correct, but when I try to do the login with the post (as you can see I have try without codification and basic), I always receive a 200 Ok, but I receive an HTML page for logging and I don't get the session cookie, that's what is killing me.
I asked my friend and he told me, he didn't modify the authentication of Django framework, so I suppose is not digest. Any idea what I am doing wrong?
Thank you in advance ;)

Related

Cant authenticate my ACS token

Ive been trying to send messages to a azure service bus queue from android for a while and i just cant get it to work. This is the code i use for getting the ACS SWT:
private void getTokenFromACS() throws ClientProtocolException, IOException {
HttpClient httpclient = new DefaultHttpClient();
HttpPost httppost = new HttpPost("https://servicebusnamespace-sb.accesscontrol.windows.net/WRAPv0.9/");
List<NameValuePair> parameters = new ArrayList<NameValuePair>(3);
parameters.add(new BasicNameValuePair("wrap_name", "name"));
parameters.add(new BasicNameValuePair("wrap_password", "password associated with the name"));
parameters.add(new BasicNameValuePair("wrap_scope", "Realm url"));
httppost.setEntity(new UrlEncodedFormEntity(parameters));
BasicHttpResponse httpResponse = null;
httpResponse = (BasicHttpResponse)httpclient.execute(httppost);
BufferedReader reader = new BufferedReader(new InputStreamReader(httpResponse.getEntity().getContent(), "UTF-8"));
String[] tokenVariables = URLDecoder.decode(reader.readLine()).split("&wrap_access_token_expires_in=");
authorizationToken = tokenVariables[0];
}
This works fine, i get a string that has the wrap_access_token, issuer, audience, expiresOn and HMACSHA256.
What i try to do after that is to send a message with this token like this:
HttpClient requestClient = new DefaultHttpClient();
HttpPost post = new HttpPost("https://servicebusnamespace.servicebus.windows.net/queuename/messages");
post.addHeader("Authorization", "WRAP access_token=\""+authorizationToken+"\"");
Item item = new Item();
Date date = new Date();
item.setDate(date);
item.setId(1);
item.setRoadName("roadname");
item.setSpeed(60.0);
item.setLat(12.12);
item.setLng(12.12);
String json = new GsonBuilder().create().toJson(item, Item.class);
post.setEntity(new ByteArrayEntity(json.getBytes("UTF8")));
HttpResponse httpResponse = requestClient.execute(post);
This always result in my Token not being authenticated, i get the error message saying my token doesnt containt a signature or that it doesnt have the audience set. What could be wrong?
Note that this is on android =)
Thanks in advance!
Seems like you are missing some code. Your authorizationToken is currently something like this: "wrap_access_token=net.windows.servicebus.action%3dLis..."
The only thing you want is the part after the equal-sign.
I think this will do:
String[] tokenVariables = URLDecoder.decode(reader.readLine()).split("&wrap_access_token_expires_in=")[0].split("=");
authorizationToken = tokenVariables[1];

Android - Cookies in HttpContext is not retrieving more than once for each URL

I'm trying to retrieve JSon information for a server that is protected and is redirected to the login page everytime that is trying to get a protected resource. So I should use cookies to implement the access to the information.
Unfortunately POST for each URL(in total 3)that I have, is just working once.
To log in the app is made using the function below:
// Making HTTP request
try {
httpClient = getNewHttpClient();
String redirectedUrl = getUrl(url);
// defaultHttpClient
HttpPost httpPost = new HttpPost(redirectedUrl);
List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(2);
nameValuePairs.add(new BasicNameValuePair("username", login));
nameValuePairs.add(new BasicNameValuePair("password", password));
httpPost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
httpContext = new BasicHttpContext();
CookieStore mCookieStore = new BasicCookieStore();
httpContext.setAttribute(ClientContext.COOKIE_STORE, mCookieStore);
HttpResponse response = httpClient.execute(httpPost, httpContext);
HttpEntity entity = response.getEntity();
String html = null;
if (entity != null) {
InputStream instream = entity.getContent();
try {
html = streamToString(instream);
} finally {
instream.close();
}
}
if ((html != null) && html.contains("error loginError")) {
} else
return html;
} catch (IOException e) {
}
And after the log in I'm trying to get the information in the same way, but it's just working once per URL. I don't know why, below is how I'm trying to get the information after login.
HttpPost httpPost = new HttpPost(url);
HttpResponse response = httpClient.execute(httpPost, httpContext);
HttpEntity entity = response.getEntity();
String html = null;
if (entity != null) {
InputStream instream = entity.getContent();
try {
html = streamToString(instream);
} finally {
instream.close();
}
}
When I'm trying to get the information second time the IOException is throwed, the httpClient and httpContext are both global and static.
I got a solution, I don't think that is a good solution, but it is working at all.
To make it stops to get the IOException, I just made a call to the login function before all post, which means that for all POSTs I have to set a new HTTPContext logged and valid.
If somebody has a better solution I would be pleasure to hear it from you.
PS.: Actually the problem was about the session duration on server side, now it's working properly, anyway I'll let the topic here because could be useful to somebody that is implementing this kind of solution.

How to let the app login automactically without opening the web?

I'm planning to make an application that can let the user accessing the Internet without opening the browser and type the login information to get the permission but just one click. I have no idea how to let the application open a web and fill the information without using a browser. Can anyone give me some suggestions?
Visit the login page of the website and examine the login form. Then use the DefaultHttpClient to send a Post request for the login.
This is roughly how I am using it:
public Boolean login() throws Exception {
DefaultHttpClient httpClient = new DefaultHttpClient();
// add login data (edit this to fit your website)
List<NameValuePair> nvps = new ArrayList<NameValuePair>();
nvps.add(new BasicNameValuePair("NAME_OF_USERNAME_FIELD", USERNAME));
nvps.add(new BasicNameValuePair("NAME_OF_PASSWORD_FIELD", PASSWORD));
// create the request
HttpPost httpost = new HttpPost(LOGIN_URL);
httpost.setEntity(new UrlEncodedFormEntity(nvps, DEFAULT_ENCODING));
// execute the form
HttpResponse response = httpClient.execute(httpost);
BufferedReader reader = new BufferedReader(new InputStreamReader(response.getEntity()
.getContent(), DEFAULT_ENCODING));
// fetch the result of the http request and save it as a string
String line;
StringBuilder sb = new StringBuilder();
while ((line = reader.readLine()) != null) {
sb.append(line).append("\n");
}
String input = sb.toString();
// check if the login worked. This depends on the response of your website
Pattern pattern = Pattern.compile(LOGIN_WORKED_PATTERN);
Matcher m = pattern.matcher(input);
if (m.find())
return true;
return false;
}
Adjust the code to fit your needs.

http post successfully logged in?

I am trying to login to a webside which needs 3 parameters in the post command.
Token, usr_name and usr_password.
The token always has the following value "545616f1e29bc538843ec7aa908122b1e".
I am getting this value by doing a HttpGet on the loginpage and store it as a string.
If i do a login through the url as follows https://www.xxxxx.com/xxxx/restricted/form/formelement=0123?usr_name=myuser&usr_password=mypass&token=545616f1e29bc538843ec7aa908122b1e the login succeeds.
How do i get a.m link build together and know afterwards that i successfully logged in?
Thanks for any tips and helping me out.
My code:
try {
String webPage = "https://xxxxxxxx.com/xx/Authenticationserv";
String name = username; // user input through editbox
String password1 = password; // user input through editbox
String authString = name + ":" + password1 + ":" + token + "=" + value;
System.out.println("auth string: " + authString);
byte[] authEncBytes = Base64.encodeBytesToBytes(authString.getBytes());
String authStringEnc = new String(authEncBytes);
System.out.println("Base64 encoded auth string: " + authStringEnc);
URL url = new URL(webPage);
URLConnection urlConnection = url.openConnection();
urlConnection.setRequestProperty("Authorization", "Basic " + authStringEnc);
InputStream is = urlConnection.getInputStream();
InputStreamReader isr = new InputStreamReader(is);
int numCharsRead;
char[] charArray = new char[1024];
StringBuffer sb1 = new StringBuffer();
while ((numCharsRead = isr.read(charArray)) > 0) {
sb1.append(charArray, 0, numCharsRead);
}
String result = sb1.toString();
System.out.println("/// BEGIN ///");
System.out.println(result);
System.out.println("/// END ///");
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
Actually I think you need to use POST method to log in in your website.I had the same problem a few weeks ago and I've did this :
HttpClient httpclient;
HttpPost httppost;
ArrayList<NameValuePair> postParameters;
httpclient = new DefaultHttpClient();
httppost = new HttpPost("your login link");
postParameters = new ArrayList<NameValuePair>();
postParameters.add(new BasicNameValuePair("username_hash", "fcd86e8cc9fc7596f102de7b2b922e80c6e6fac9"));
postParameters.add(new BasicNameValuePair("password_hash", "b66936348bd0bd44fa44f5ca7dcceb909545e47f"));
httppost.setEntity(new UrlEncodedFormEntity(postParameters));
HttpResponse response = httpclient.execute(httppost);
Log.w("Response ","Status line : "+ response.toString());
So you are setting up your post params with an ArrayList and you can get the responce from the server if you logged in via HttpResponse.And another thing : I'm setting up the username and password in the code,because it is just to how you the idea.If you have any questions feel free to ask.
Hope it helps!

Android Webview POST

I am trying to accomplish something quite simple, yet I have found no good documentation on this. I have a webView, and I need to load a page in it that requires POST data. Seems like a simple process, yet I cannot find a way to display the result in a webView.
The process should be simple:
query(with POST data) -> webserver -> HTML response -> WebView.
I can submit data using a DefaultHttpClient, but this cannot be displayed in a WebView.
Any suggestions?
Much Thanks
Solution
private static final String URL_STRING = "http://www.yoursite.com/postreceiver";
public void postData() throws IOException, ClientProtocolException {
List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>();
nameValuePairs.add(new BasicNameValuePair("foo", "12345"));
nameValuePairs.add(new BasicNameValuePair("bar", "23456"));
HttpClient httpclient = new DefaultHttpClient();
HttpPost httppost = new HttpPost(URL_STRING);
httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
HttpResponse response = httpclient.execute(httppost);
String data = new BasicResponseHandler().handleResponse(response);
mWebView.loadData(data, "text/html", "utf-8");
}
Two ways to load post response in webview:
webview.loadData(): Like what you have posted in your solution. But "content loaded through this mechanism does not have the ability to load content from the network".
webview.postUrl(): Use this if post response needs to load content from the network. (NOTE: only accessible from api-level 5, which means no android 1.6 or lower)
String postData = "username=my_username&password=my_password";
webview.postUrl(url,EncodingUtils.getBytes(postData, "BASE64"));
(source: http://www.anddev.org/other-coding-problems-f5/webview-posturl-postdata-t14239.html)
Try this:
private static final String URL_STRING = "http://www.yoursite.com/postreceiver";
public void postData() throws IOException, ClientProtocolException {
List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>();
nameValuePairs.add(new BasicNameValuePair("foo", "12345"));
nameValuePairs.add(new BasicNameValuePair("bar", "23456"));
HttpClient httpclient = new DefaultHttpClient();
HttpPost httppost = new HttpPost(URL_STRING);
httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
HttpResponse response = httpclient.execute(httppost);
}
I would recommend doing this as part of an AsyncTask and updating the WebView afterwards
I use webView.loadData() to do client post, and it will display content of url, my code :
public static void webview_ClientPost(WebView webView, String url, Collection< Map.Entry<String, String>> postData){
StringBuilder sb = new StringBuilder();
sb.append("<html><head></head>");
sb.append("<body onload='form1.submit()'>");
sb.append(String.format("<form id='form1' action='%s' method='%s'>", url, "post"));
for (Map.Entry<String, String> item : postData) {
sb.append(String.format("<input name='%s' type='hidden' value='%s' />", item.getKey(), item.getValue()));
}
sb.append("</form></body></html>");
webView.loadData(sb.toString(), "text/html", "UTF-8");
}
use function webview_ClientPost() :
Map<String, String> mapParams = new HashMap<String, String>();
mapParams.put("param1", "111");
mapParams.put("param2", "222");
Collection<Map.Entry<String, String>> postData = mapParams.entrySet();
webview_ClientPost(webView1, "http://www.yoursite.com/postreceiver", postData);
If you use a WebView from the start could it work?
A Webview with a html/js that does the POST, and naturally displays the result.
You can also pass post key:value pair in JSON format to web view.
String userName = "admin";
String password = "Admin#2021";
JSONObject jsonObject = new JSONObject();
try {
jsonObject.put("userName", userName);
jsonObject.put("password", password);
} catch (JSONException e) {
e.printStackTrace();
}
String url = "http://www.example.com";
webView.postUrl(url, jsonObject.toString().getBytes());

Categories

Resources