Android App that logs in to HTTPS ASPX page - java

Just to make things clear, I have virtually no experience in HTTP. This project is very ambitious for me, but I am willing to learn in order to be able to accomplish it. I have done some searching for examples across the net, but I can't seem to find an adequate solution. I am aware of terms like GET and POST and understand the basic way to programmatically interact with a website.
Basically, the company I'm working with has a website with a database of clients that I can login to. For starters, I just want to be able to write an Android app that is able to login to the main page with my Username and Password. The site has a login URL of https://"app.companysite.com"/Security/Login.aspx?ReturnUrl=%2fHome%2fDefault.aspx and has a certificate that is for the following purpose: "Ensures the identity of a remote computer".
Is what I'm doing possible? Eventually I would like to be able to open up a Client page and edit their data and re-submit it, but one step a time.
It would be awesome if you could either point me in the direction of some relevant reading material or source code that could help me accomplish my goal.
Thanks in advance!

I don't know if this helps, but the way I did my logins is just for justification. So What I did (since I am assuming the verification is done through a MySQL database) is to create a php file that just verifies the login username and passwords are correct and print out a "correct" or "Yes" otherwise just a "No" or "invalid". Something like this :
php
//Connects to your Database
$username = $_POST['username'];
$password = $_POST['password'];
//make your mysql query if the username and password are in the database
//if there is a an approval
$approval = 1
//otherwise
$approval = 0
if ($approval > 0) {
echo "correct";
} else {
echo "invalid";
}
?>
Now in Android you could make this request to call this website and return the output like the following :
HttpParams httpParameters = new BasicHttpParams();
//make a timeout for the connections in milliseconds so 4000 = 4 seconds httpParameters.setParameter(CoreProtocolPNames.PROTOCOL_VERSION, HttpVersion.HTTP_1_1);
int timeoutConnection = 4000;
HttpConnectionParams.setConnectionTimeout(httpParameters, timeoutConnection);
int timeoutSocket = 4000;
HttpConnectionParams.setSoTimeout(httpParameters, timeoutSocket);
HttpClient httpclient = new DefaultHttpClient(httpParameters);
HttpPost httppost = new HttpPost("your website URL");
// Add your data
String username = "your username";
String password = "your password";
List<NameValuePair> nameValuePairs;
nameValuePairs = new ArrayList<NameValuePair>(2);
nameValuePairs.add(new BasicNameValuePair("username", username));
nameValuePairs.add(new BasicNameValuePair("password", password));
httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
// Execute HTTP Post Request
HttpResponse response = httpclient.execute(httppost);
BufferedReader in = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));
String lines = "";
String data = null;
ArrayList<String> al = new ArrayList<String>();
while((lines = in.readLine()) != null){
data = lines.toString();
al.add(data);
}
in.close();
//To get the response
if(al.get(0).equals("correct")){
//Your login was successful
}
else {
//Your login was unsuccessful
}
I hope this helped you a bit and pointed you in the right direction.

Related

eclipse android pass a java value to php by using HTTP

I want to pass the variable q from java to php.
String q = "select author from books where 1";
try{
HttpClient httpClient = new DefaultHttpClient();
HttpPost httpPost = new HttpPost("http://www2.XXXX./XXXX/X.php?qy="+q);
//"http://10.0.2.2/tut.php", http://www.XXXX/XXXX/tut.php
HttpResponse response = httpClient.execute(httpPost);
HttpEntity entity = response.getEntity();
is = entity.getContent();
}catch(Exception e){
e.printStackTrace();
System.out.println("Exception 1 caught");
}
However, the php file cannot get the value from java(php connected to mysql correctly).
php coding:
<?php
$con=mysql_connect("XXX.XXX","XX","XXX");
mysql_select_db("XX",$con);
$st = $_GET['qy'];
$r = mysql_query("$st");
while($row=mysql_fetch_array($r))
{
$out[]=$row;
}
print(json_encode($out));
mysql_close($con);
?>
I found that if I just pass the table name to php, it works. But if the passing variable become longer, it went to caught one. How can I fix this? How about passing more than one variable to php (i.e. mysql_query("select $_GET['col'] from $_GET['table'] where $_GET['condition']");)?
Use Post instead of Get, it's more secure.
Something like this:
String col = "author";
String table = "books";
String condition = "1";
try{
List<NameValuePair> params = new ArrayList<NameValuePair>();
params.add(new BasicNameValuePair("col", col));
params.add(new BasicNameValuePair("table", table));
params.add(new BasicNameValuePair("condition", condition));
HttpClient httpClient = new DefaultHttpClient();
HttpPost httpPost = new HttpPost("http://www2.XXXX./XXXX/X.php");
httpPost.setEntity(new UrlEncodedFormEntity(params));
HttpResponse response = httpClient.execute(httpPost);
HttpEntity entity = response.getEntity();
is = entity.getContent();
}catch(Exception e){
e.printStackTrace();
System.out.println("Exception 1 caught");
}
PHP:
<?php
if (isset($_POST['col']) && isset($_POST['table']) && isset($_POST['condition'])){
$columnName= $_POST['col'];
$tableName = $_POST['table'];
$condition = $_POST['condition'];
$dbh=mysql_connect ("localhost", "username", "password") or die('Cannot connect to the database because: ' . mysql_error());
mysql_select_db ("database_name");
$sql=mysql_query("select '$columnName' from '$tableName' where '$condition'");
while($row=mysql_fetch_assoc($sql)) $output[]=$row;
print(json_encode($output));
mysql_close();
}
?>
it works(by mandi yeung)
Never ever send any queries to backend. Your approach is equivalent to an EditText where user can execute desired query on your database. Keep your queries out of your requests at any cost. Query parts (as previous uaer suggested) count too. Query parts from request actually do the same thing.
Sending select query to backend may (and totally will) grant any attacker full access to your database. That means he may change or just delete the data.
I could just tamper your web packet and send drop table statement instead.
drop table authors;
drop table books;
sBetterapproach would be sending json requests like this:
String query = "{
requestedData: getAllBooks,
sessionId: 637euegdifoidhrgeydydihvr
}";
new BasicNameValuePair("smth", query);
Then from your php side you read your input as a plain text $_POST["smth"].
You must then decode your json value into object or array and determine what query you must run.
if ($_GET["smth"]["requestedData"] === "getBooks") {
// get books query executed here
}
Remember: this approach is still not perfect, but it's better than yours

Android get Returned value from php

I am interfacing my Android app with my Drupal website. In my app I am creating user accounts to that website using the standard PHP user_save. What I need to move my app from the current activity to the next is a value to be returned form that PHP form which is creating my Drupal user account.
SO when an account is created, a value of 'invalid' or 'valid' would be returned from the php form like so:
// User Authentication
$responsep="valid";
$responsen="invalid";
if(!user_authenticate($username, $password)){
drupal_json_output($responsen);
}else{
// Logs the USER in
$account = user_authenticate($username, $password);
$user = user_load($account, TRUE);
drupal_session_regenerate();
drupal_json_output($responsep);
}
Question is, how do I, in my android java method, retrieve that returned value of either valid or invalid so that I may use it to make other decisions such as try agin or change activities?
I have updated the code above
Here is the part from my App which is sending the user data:
public void createUserAccount(String usernameFinal, String passwordFinal,
String userEmail) throws ClientProtocolException, IOException {
// POST Username data to php
String uri = "https://url/hstusercreate.php";
Log.d("Action", "Posting user data to php");
HttpClient client = new DefaultHttpClient();
HttpPost getMethod = new HttpPost(uri);
Log.d("Posting Location", uri);
ArrayList<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>();
Log.d("Posting Username", usernameFinal);
nameValuePairs.add(new BasicNameValuePair("username", usernameFinal));
Log.d("Posting Pass", passwordFinal);
nameValuePairs.add(new BasicNameValuePair("password", passwordFinal));
//Log.d("Posting Email", userEmail);
//nameValuePairs.add(new BasicNameValuePair("email", userEmail));
getMethod.setEntity(new UrlEncodedFormEntity(nameValuePairs, HTTP.UTF_8));
client.execute(getMethod);
Log.d("Action", "Finished Posting Data to PHP");
// Return the message from php
// If Successful then stop the creation of another user
}
The easiest thing to do would be to return either JSON or XML from your PHP which your app can then read and parse.
Actually you could even just print "valid" or "invalid" on the page, and then use something like JSoup in your app to read the webpage and extract the string.

how to pass arguments to GET method in RESTfull webservice

I have to pass UserName and password as arguments into GET method for validation.after processing I need to get response.so how can I pass value into RESTful webservice GET method?
To pass parameters in HTTP GET you should use a ? delimiter. Such as
https://mywebsite.com/user/login?username=bob&password=123
https://mywebsite.com/user/login?paramname1=value1&paramname2=value2
Make sure to always use https with any sensitive data. You may also need to escape/encode both username and password to allow extended ASCII. If you need to support UNICODE you should consider using a POST request.
I think, you should use POST method if you want to do something with user name and password. because when you use GET method, the password would be visible on the URI,
https://samplesite.com/page/login?username=John&password=123
https://sampleste.com/page/login?name1=value1&name2=value2
Instead, you could use POST method to send user name and password values and in that case the URI would like below
https://samplesite.com/page/login
And the values will be sent as,
POST /page/login.asp HTTP/1.1
Host: samplesite.com
name1=value1&name2=value2
And you get below advantages on POST Method for secured transaction with server.
It never cached
Requests will remain in the browser history
Requests cannot be bookmarked
Requests have no restrictions on data length
You can do the following for Login validation,
// Create a new HttpClient and Post Header
String downloadedString= null;
HttpClient httpclient = new DefaultHttpClient();
//for registerhttps://te
HttpPost httppost = new HttpPost("YOUR LOGIN URL");
//add data
try{
List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(2);
nameValuePairs.add(new BasicNameValuePair("username", UserName_Edit.getText().toString()));
nameValuePairs.add(new BasicNameValuePair("password", userPassword_Edit.getText().toString()));
//add data
httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
// Execute HTTP Post Request
HttpResponse response = httpclient.execute(httppost);
InputStream in = response.getEntity().getContent();
StringBuilder stringbuilder = new StringBuilder();
BufferedReader bfrd = new BufferedReader(new InputStreamReader(in),1024);
String line;
while((line = bfrd.readLine()) != null)
stringbuilder.append(line);
downloadedString = stringbuilder.toString();
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
System.out.println("downloadedString:in login:::"+downloadedString);
Use AsyncTask for your authentication and write the above method in the doInBackground().
EDIT
You can follow below tutorials also,
http://sarangasl.blogspot.in/2011/06/android-login-screen-using-httpclient.html
http://www.androidhive.info/2012/01/android-login-and-registration-with-php-mysql-and-sqlite/
Hope it helps.
Hi you can pass arguments to GET method in RESTfull like :
http://yoururl/<arg1>/<arg2>
eg.
http://yoururl/abc/123

Android HttpClient and Cookies

I have a problem with the HttpClient in Android: By using the following code, I want to use the cookies which are already set before by logging in through a webview. So the login data should be there and is indeed there, I tested it. But when I use the cookies in an httppost or httpget it doesn't use the login data. but these cookies actually should be enough to receive that page for which a login is necessary, shouldn't they? I'm not really sure if I need to send the cookies in a special way to the server or so or if it is enough to load it into the httpcontext. Here is the code:
DefaultHttpClient httpclient = new DefaultHttpClient();
CookieStore lCS = new BasicCookieStore();
if (CookieManager.getInstance().getCookie(pUrl) != null) {
String cookieString = CookieManager.getInstance().getCookie(pUrl);
String[] urlCookieArray = cookieString.split(";");
for (int i = 0; i < urlCookieArray.length; i++) {
System.out.println(urlCookieArray[i]);
String[] singleCookie = urlCookieArray[i].split("=");
Cookie urlCookie = new BasicClientCookie(singleCookie[0], singleCookie[1]);
lCS.addCookie(urlCookie);
}
}
HttpContext localContext = new BasicHttpContext();
httpclient.setCookieStore(lCS);
localContext.setAttribute(ClientContext.COOKIE_STORE, lCS);
HttpPost httppost = new HttpPost(pUrl);
// get the url connection
try {
StringBuilder sb = new StringBuilder();
HttpResponse response = httpclient.execute(httppost, localContext);
InputStream is = response.getEntity().getContent();
InputStreamReader isr = new InputStreamReader(is);
And if I run the code I only receive the login page of that site, so it didn't accept the cookie.
Thanks for help in advance
Greets, timo
I had the same problem and I used similar approach as in the question with no luck.
The thing that made it work for me was to add the domain for each copied cookie.
(BasicClientCookie cookie.setDomain(String))
My util function:
public static BasicCookieStore getCookieStore(String cookies, String domain) {
String[] cookieValues = cookies.split(";");
BasicCookieStore cs = new BasicCookieStore();
BasicClientCookie cookie;
for (int i = 0; i < cookieValues.length; i++) {
String[] split = cookieValues[i].split("=");
if (split.length == 2)
cookie = new BasicClientCookie(split[0], split[1]);
else
cookie = new BasicClientCookie(split[0], null);
cookie.setDomain(domain);
cs.addCookie(cookie);
}
return cs;
}
String cookies = CookieManager.getInstance().getCookie(url);
BasicCookieStore lCS = getCookieStore(cookies, MyApp.sDomain);
HttpContext localContext = new BasicHttpContext();
DefaultHttpClient httpclient = new DefaultHttpClient();
httpclient.setCookieStore(lCS);
localContext.setAttribute(ClientContext.COOKIE_STORE, lCS);
...
if you still have this problem, be careful with the given cookies, some might be malformed, check these two sites out:
http://www.codeproject.com/Articles/3106/On-The-Care-and-Handling-of-Cookies
this one helped me:
Getting "Set-Cookie" header
It seems you are copying the cookies correctly, and generally you don't need to do anything special for HttpClient to send the cookies. However, some of those may be bound to a session, and when you open a new connection with HttpClient you open a new session. The server will probably ignore cookies that don't match the current session. This might work if the session ID is in a cookie and you are able to get into the same session, but you really need to know exactly what the server does.

REST PUT Response format

I have an android application with a MySQL database. Rows entered on the android tablet need to be synchronised on a server, also with MySql. Once written onto the server the server Unique Integer needs to be returned to the tablet to update the local database. That way it will x-ref the client to the server. It currently works by performing a PUT for each row and using the location for the server ID in the response. However it takes ages if there are a significant amount of updates, inserts as each one row opens a new HttpConnection. I would like to be able to group the updates in one XML String and get an XML file returned with the xreference of the serverID for each Client ID. However I cannot find a way of sending XML in the response, only a URI. My connection code is
HttpParams httpParameters = new BasicHttpParams();
HttpConnectionParams.setConnectionTimeout(httpParameters, Const.HTTP_CONNECTION_TIMEOUT);
HttpConnectionParams.setSoTimeout(httpParameters, Const.HTTP_SOCKET_TIMEOUT);
DefaultHttpClient client = new DefaultHttpClient(httpParameters);
client.getCredentialsProvider().setCredentials(AuthScope.ANY,new UsernamePasswordCredentials("xxxxx","xxxxx")); // TODO Change to logged user name
HttpPut put = new HttpPut(uri);
StringEntity entity = new StringEntity(xml);
entity.setContentType("application/xml");
put.setEntity(entity);
HttpClientParams.setRedirecting(put.getParams(), false);
HttpResponse response = client.execute(put);
switch (response.getStatusLine().getStatusCode()){
case 200:
case 201:
location = response.getLastHeader("Location").getValue();
key = location.substring(location.lastIndexOf("/")+1);
break;
case 401:
throw new RuntimeException("Authorisation Failed");
default:
throw new RuntimeException("Failed to Create Data Record on Server");
}
And on the Server
if (flight.getClientFlightId()!=0){
if (insertFlight(userId)){
xref += "<clientId>"+flight.getClientFlightId()+"</clientId><serverId>"+flight.getServerFlightId()+"</serverId>";
}
}
xref +="</xref>";
response = Response.created(URI.create(xref)).build();
Anyone able to help please?
ArrayList<NameValuePair> putParams = new ArrayList<NameValuePair>();
putParams.add(new BasicNameValuePair("myXML", "<xml> _PUT_YOUR_XML_HERE_ </xml>"));
UrlEncodedFormEntity formEntity = new UrlEncodedFormEntity(putParams);
put.setEntity(formEntity);

Categories

Resources