Android - Form based authentication - android

I need to upload some data on a site, using a POST request. I know to use HTTP client to execute a POST request
The problem is that in order to do this, you should authenticate first.
The site is a simple page prompting for a username and a password. I assume it stores a cookie in the browser and checks subsequent requests to see if I'm already authenticated.
But I don't have a concrete idea how to implement this on Android.
The client just gave me this:
URL to upload: http://xyz.com/?page=add
Credentials: admin/admin
Format of data:
$_POST = {
["Name"]=>string(255)
["Address"]=>string(255)
["ZIP"]=>string(50)
["City"]=>string(100)
["Phone"]=>string(50)
["Email"]=>string(50)
["Age"]=>int(11)
["Validation_Result"]=>string(255)
["Comment"]=>string(-)
}
$_FILES["Image"] = {
["name"]=>string "3D-graphics_3D_Triangles_006790_.jpg"
["type"]=>string "image/jpeg"
["tmp_name"]=>string "C:\Windows\Temp\php1362.tmp"
["error"]=>int(0)
["size"]=>int
}
And nothing else.
Could you please point me in the right direction how I would go about doing this?

How to do HTTP authentication in android?
Check out the top answer on this question. Very good explanation.

If you are doing the POST using HttpClient as the post you linked describes, you can add Basic Authentication by doing the following:
String username, password;
DefaultHttpClient client = new DefaultHttpClient();
UsernamePasswordCredentials creds = new UsernamePasswordCredentials(username, password);
client.getCredentialsProvider().setCredentials(AuthScope.ANY, creds);
HTH

I know this is a very old question, but this was the top search result I kept running into and I wanted to add another way that I managed to do this using CookieStore and HttpClient.
For my use case (Tomcat server configuration), I was hitting my base authenticated URL to get the cookie, POSTing my auth data to the form submission endpoint, and then using the cookie for subsequent calls. Here's the simplified piece of code that got it working for me:
String cookieUrl = "SOME_URL_THAT_WILL_PROVIDE_COOKIE";
String authenticateUrl = "URL_TO_POST_FORM_DATA";
String dataUrl = "AUTHENTICATED_URL_YOU_WANT_DATA_FROM";
final String userNameKey = "FORM_KEY_FOR_USERNAME";
final String userPassKey = "FORM_KEY_FOR_PASSWORD";
final String userName = "USER_NAME";
final String userPass = "USER_PASSWORD";
HttpClient client = new DefaultHttpClient();
CookieStore cookieStore = new BasicCookieStore();
HttpContext context = new BasicHttpContext();
context.setAttribute(ClientContext.COOKIE_STORE, cookieStore);
String getUrl = cookieUrl;
HttpGet get = new HttpGet( getUrl );
HttpResponse getResponse = client.execute(get, context);
Log.d( "ConnectionTest", "GET # " + getUrl );
Log.d( "ConnectionTest", getResponse.getStatusLine().toString() );
List<NameValuePair> authDataList = new ArrayList<NameValuePair>();
authDataList.add( new NameValuePair() {
#Override
public String getName() {
return userNameKey;
}
#Override
public String getValue() {
return userName;
}
} );
authDataList.add( new NameValuePair() {
#Override
public String getName() {
return userPassKey;
}
#Override
public String getValue() {
return userPass;
}
} );
HttpEntity authEntity = new UrlEncodedFormEntity( authDataList );
String authPostUrl = authenticateUrl;
HttpPost authPost = new HttpPost( authPostUrl );
authPost.setEntity( authEntity );
HttpResponse authPostResponse = client.execute(authPost, context);
Log.d( "ConnectionTest", "POST # " + authPostUrl );
Log.d( "ConnectionTest", authPostResponse.getStatusLine().toString() );
String getUsersUrl = dataUrl;
HttpGet usersGet = new HttpGet( getUsersUrl );
HttpResponse usersGetResponse = client.execute(usersGet, context);
Log.d( "ConnectionTest", "GET # " + getUsersUrl );
Log.d( "ConnectionTest", usersGetResponse.getStatusLine().toString() );
Log.d( "ConnectionTest", EntityUtils.toString( usersGetResponse.getEntity() ) );

Related

How can we follow/Unfollow instagram in android app?

When I use Follow/Unfollow API in instagram. I give me error like that.
Error:
{"meta":{"error_type":"OAuthPermissionsException","code":400,"error_message":"This client has not been approved to access this resource."}}
My Post method Call is here.
public static AllMessage postAction(String action, String UserID, String mAccessToken, DefaultHttpClient httpClient) {
AllMessage ReturnMessage = new AllMessage();
String url = String.format(RELATIONSHIP_URL, new Object[]{UserID, mAccessToken});
Log.v("log_tag", "FolURL " + url);
try {
HttpParams params = new BasicHttpParams();
params.setParameter("http.protocol.version", HttpVersion.HTTP_1_1);
params.setParameter("action=", action);
if (httpClient == null) {
httpClient = OpenHttpClientConnection();
}
HttpPost httpPost = new HttpPost(url);
List<NameValuePair> arrayList = new ArrayList(2);
arrayList.add(new BasicNameValuePair("action", action));
httpPost.setHeader("Accept", "application/json");
httpPost.setHeader("Content-type", String.valueOf(arrayList));
UrlEncodedFormEntity ent = new UrlEncodedFormEntity(arrayList, "UTF-8");
httpPost.setEntity(ent);
String mHttpReturnedData = readInputStreamToString(httpClient.execute(httpPost).getEntity().getContent());
Log.v("log_tag", "Return " + mHttpReturnedData);
} catch (Exception e4) {
ReturnMessage.MessageType = "Unsupported Format";
ReturnMessage.MessageError = "Unsupported data format Error -1000";
ReturnMessage.ActionSucess = false;
ReturnMessage.ActionID = 0;
ReturnMessage.PrvAction = action;
}
return ReturnMessage;
}
Please help me for this code.
You need to first register your app to use the Instagram API
The link is here https://www.instagram.com/developer/endpoints/
Then you comunicate with the endpoint https://api.instagram.com/v1/tags/nofilter/media/recent?access_token=ACCESS_TOKEN
and make the proper calls.
Currently there is not an Android SDK made by them that I have heard of, but I'm pretty sure there has to be a 3rd party out there.
Hope it helps.

Consume ASP.NET WebApi HTTP service in Android with HTTP POST

I have implemented ASP.NET WebApi and consumed in Android application with HTTPPOST. Parameter less methods are calling perfectly but method with parameters not working while it is working fine with Advanced Rest Client in Google Chrome also working perfectly with HTTP GET.
Caller Code in Android:
String url = "http://192.168.15.3/api/user"
HttpPost postMethod = new HttpPost(url);
postMethod.setHeader("Content-Type", "application/json; charset=utf-8");
postMethod.setHeader("Accept", "*/*");
postMethod.setHeader("Accept-Encoding", "gzip, deflate");
postMethod.setHeader("Accept-Language", "en-US,en;q=0.8");
List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>();
nameValuePairs.add(new BasicNameValuePair("id", "1"));
DefaultHttpClient hc = new DefaultHttpClient();
HttpResponse response;
postMethod.setEntity(new UrlEncodedFormEntity(nameValuePairs, "UTF-8"));
response = hc.execute(postMethod);
HttpEntity entity = response.getEntity();
InputStream inStream = entity.getContent();
String result = convertStreamToString(inStream);
Log.e("Result: ", result);
Controller:
public class UserController : ApiController
{
UserCredentials[] users = new UserCredentials[]
{
new UserCredentials { User_ID = "1", User_Name = "testuser", Password = "test", First_Name = "Test", Last_Name = "User",
Email = "testuser#dummy.com", Phone ="123456789", Mobile = "123456789", User_Type = "user" },
new UserCredentials { User_ID = "2", User_Name = "testuser2", Password = "test", First_Name = "Test", Last_Name = "User",
Email = "testuser2#dummy.com", Phone ="123456789", Mobile = "123456789", User_Type = "user" }
};
[AcceptVerbs("POST")]
public IEnumerable<UserCredentials> GetAllUsers()
{
return users;
}
[AcceptVerbs("POST")]
public IHttpActionResult GetUser(string id)
{
var user = users.FirstOrDefault((p) => p.User_ID.Equals(id));
if (user == null)
{
return NotFound();
}
return Ok(user);
}
}
Error:
{"Message":"No HTTP resource was found that matches the request URI 'http://192.168.15.3/api/user'.","MessageDetail":"No action was found on the controller 'User' that matches the request."}
It is throwing an error because your controller does not have any matching httppost method. You are trying to post data to method which accepts GET request.
WebApi works on convention based method names. Your methods starts with "Get" so it will map requests in below manner :
Get All users - GET - /api/users
Get user by Id - GET - /api/users/id
So you can call them using HttpGet request and not POST.

Twitter API USERS/Search returns Forbidden in Android App

My MainActivity.java has these declarations
final static String CONSUMER_KEY = "MY-CONSUMER-KEY";
final static String CONSUMER_SECRET = "MY-CONSUMER-SECRET";
final static String TwitterTokenURL = "https://api.twitter.com/oauth2/token";
final static String TwitterStreamURL = "https://api.twitter.com/1.1/statuses/user_timeline.json?screen_name=";
final static String TwitterUsersURL = "https://api.twitter.com/1.1/users/search.json?q=";
I'm using the following code in an async task to search for users
String urlApiKey = URLEncoder.encode(MainActivity.CONSUMER_KEY, "UTF-8");
String urlApiSecret = URLEncoder.encode(MainActivity.CONSUMER_SECRET, "UTF-8");
String combined = urlApiKey + ":" + urlApiSecret;
String base64Encoded = Base64.encodeToString(combined.getBytes(), Base64.NO_WRAP);
HttpPost httpPost = new HttpPost(MainActivity.TwitterTokenURL);
httpPost.setHeader("Authorization", "Basic " + base64Encoded);
httpPost.setHeader("Content-Type", "application/x-www-form-urlencoded;charset=UTF-8");
httpPost.setEntity(new StringEntity("grant_type=client_credentials"));
String rawAuthorization = getResponseBody(httpPost);
Authenticated auth = jsonToAuthenticated(rawAuthorization);
if (auth != null && auth.token_type.equals("bearer")) {
// Step 3: Authenticate API requests with bearer token
HttpGet httpGet = new HttpGet(MainActivity.TwitterUsersURL + screenName);
// construct a normal HTTPS request and include an Authorization
// header with the value of Bearer <>
httpGet.setHeader("Authorization", "Bearer " + auth.access_token);
httpGet.setHeader("Content-Type", "application/json");
// update the results with the body of the response
results = getResponseBody(httpGet);
}
When I am sending request on the TwitterStreamURL, I get the proper response. But any request on TwitterUsersURL, I'm getting "Forbidden".
I've been browsing online and everyone faced this issue when they used http instead of https, which I am.
What am I doing wrong??
EDIT: I'm using Application Only Authentication

Android server data fetch

I want to fetch some data from a server protected with an username and password . I know both the username and password . Since the server is live , the data is continuing changing I need to fetch data every minute to update the application's status . The only function I know that can fetch data and turn it to a string is :
private String getPage() {
String str = "***";
try
{
HttpClient hc = new DefaultHttpClient();
HttpPost post = new HttpPost("http://mywebsite.me");
HttpResponse rp = hc.execute(post);
if(rp.getStatusLine().getStatusCode() == HttpStatus.SC_OK)
{
str = EntityUtils.toString(rp.getEntity());
}
}catch(IOException e){
e.printStackTrace();
}
return str;
}
Since the server has a logon screen I don't know how to get pass it . So , i'd like help with 2 thigs :1. getting the data from the server and 2. every 1 or 2 minutes I need to refresh my app and fetch again the data .
You can try this for the post object. Pre-emptive authentication is done this way.
HttpPost post = new HttpPost(url);
// Prepare the authentication.
String usernameAuth = "u";
String passwordAuth = "p";
post.addHeader("Authorization", "Basic " +
Base64.encodeToString((usernameAuth + ":" + passwordAuth).getBytes("UTF-8"),
android.util.Base64.NO_WRAP));
For running this at regular intervals :
mTimer.scheduleAtFixedRate(new TimerTask() {
#Override
public void run() {
// What you want to do goes here
}
}, 0, REFRESH_TIME);
I hope it helps.

How to use AndroidHttpClient (API Level 8) and UsernamePasswordCredentials?

Currently I am using a DefaultHttpClient with ThreadSafeClientConnManager. This works fine, but I would like to replace this by using AndroidHttpClient. Unfortunately I am not able to add UsernamePasswordCredentials which is currently important for me. Can anyone provide a tip or solution?
You need to use HttpRequestInterceptor class for authentication.
Here is an example
HttpRequestInterceptor httpRequestInterceptor = new HttpRequestInterceptor() {
public void process(final HttpRequest request, final HttpContext context) throws HttpException, IOException {
AuthState authState = (AuthState) context.getAttribute(ClientContext.TARGET_AUTH_STATE);
CredentialsProvider credsProvider = (CredentialsProvider) context.getAttribute(
ClientContext.CREDS_PROVIDER);
HttpHost targetHost = (HttpHost) context.getAttribute(ExecutionContext.HTTP_TARGET_HOST);
if (authState.getAuthScheme() == null) {
AuthScope authScope = new AuthScope(targetHost.getHostName(), targetHost.getPort());
Credentials creds = credsProvider.getCredentials(authScope);
if (creds != null) {
authState.setAuthScheme(new BasicScheme());
authState.setCredentials(creds);
}
}
}
};
I know the question is old but for the benefit of anyone stumbling on this (like I did), you can roll the header yourself with HttpGet object. Like so :
httpGet.addHeader("Authorization", "Basic " + Base64.encode(username+":"+password));
Some enhancement to Saad Farooq's answer, the following code works for me.
final AndroidHttpClient client = AndroidHttpClient.newInstance("Android");
getRequest = new HttpGet(url);
getRequest.addHeader("Authorization", "Basic " + Base64.encodeToString(new
String(username + ":" + password).getBytes(), Base64.NO_WRAP));

Categories

Resources