Android - Basic Authenticated HTTP Request - android

So basically i need my android app to connect to a web service using a url as such
"http://username:password#0.0.0.0" aka basic authentication.
obviously the username and password are checked by the web app before allowing access and otherwise doesn't allow the request.
my issue is that all the methods i try always say unauthorised (response code 401) regardless of what combination of classes and methods ive used to try and connect to the the url.
The web app in question is designed to return things only is un/pw clears otherwise it returns nothing, the web app and un/pw etc have all be checked and cleared.
so does anyone no the correct way to send a request to a url like that and have it work correctly?
android api8 btw
UPDATE
Turns out my issue is due to the web app using NTLM windows authentication which is not supported directly by androids/apache http library, investigating appropriate workarounds now

Here's some code form a really old project of mine. I used basic auth for some web service, and this worked at the time. I'm not sure if there are updated api's since then (this was Android 1.6), but it should still work.
HttpGet request = new HttpGet();
request.setURI(new URI(url));
UsernamePasswordCredentials credentials =
new UsernamePasswordCredentials(authUser, authPass);
BasicScheme scheme = new BasicScheme();
Header authorizationHeader = scheme.authenticate(credentials, request);
request.addHeader(authorizationHeader);
Basically, Basic HTTP auth is a simple hash of the user and password. The browser allows you to stuff these values in the url, but it actually does the work of adding the basic auth header to your request.

Related

Authentication for GET Request in Android HTTP/1.1 406 Not Acceptable

I tried but there seems to be a problem in making a GET Request to a heroku URL example "https://xxxx-xxxxx.herokuapp.com/xxxxxx/xxxxxxxx"
I know the general method is
HttpClient client = factory.getHttpClient(); //or any method to get a client instance
Credentials credentials = new UsernamePasswordCredentials(username, password);
client.getState().setCredentials(AuthScope.ANY, credentials);
And I know that getState() is not available for 3.x version.
I don't know how the Chrome's "Advance REST Client" has handled it, it gave me the pop up and asked for the username and password and I entered Credentials and it worked and since then its working fine. I thought It might have stored the credential locally but, its not the case. I checked all the cookies and cache. I deleted the extension and cleared data and its still working.
Then I tried to use another REST Client by WizTools (for Mac). In the Authorization section there are 3 options. 1.) Basic, 2.) Digest and 3.)Preemptive, I did some permutation and combination with it using the given Credentials but all the time it gave the same response i.e.
"HTTP/1.1 406 Not Acceptable"
I don't understand what's the issues is?
Thanks,
I don't know, if why is it not working, but I used URLConnecton used the authentication mentioned and it worked. I got the response. And yeah BTW I had to assign the "Accept" type a s "Application/Json"

Securing Spring Rest service

I'm trying to implement a RESTful web service using Spring. I've set up Spring Security to work on the links that apply to the REST service. I make calls to this web service from an Android application. What I've done now is connect to it using Basic Authentication. What I'm struggling with is finding decent information about how secure this really is. I figure I should at least be making these calls through SSL or something no?
My code on the Android client that calls the REST client
public MyClass callRest() {
final String url = "http://10.0.2.2:8080/myservice/rest/getSomething";
HttpAuthentication authHeader = new HttpBasicAuthentication(username,
password);
HttpHeaders requestHeaders = new HttpHeaders();
requestHeaders.setAuthorization(authHeader);
requestHeaders.setAccept(Collections
.singletonList(MediaType.APPLICATION_JSON));
RestTemplate restTemplate = new RestTemplate();
restTemplate.getMessageConverters().add(
new MappingJacksonHttpMessageConverter());
try {
ResponseEntity<MyClass> response = restTemplate.exchange(url,
HttpMethod.GET, new HttpEntity<Object>(requestHeaders),
MyClass.class);
return response.getBody();
} catch (HttpClientErrorException e) {
return new MyClass();
}
}
So what I've put in my Spring Security config right now:
<http auto-config='true'>
<intercept-url pattern="/rest/**" access="ROLE_USER"
requires-channel="https" />
</http>
I can't figure out where to go from there, because now the connection doesn't work anymore of course because of the https. I can't seem to find decent examples of how to figure this out using the Resttemplate.
Any help?
HTTP Basic Authentication is reasonably safe when used over HTTPS since the user and password fields are sent over an encrypted connection so they are much less vulnerable to man-in-the-middle attacks. There are some interesting points here: Securing an API: SSL & HTTP Basic Authentication vs Signature
In my opinion, if you are making a API with access to user's sensitive data (i.e. bank account details, credit card numbers, email addresses and passwords) then you may want a more secure approach because HTTP Basic Authentication is succeptible to brute force attacks as it is always available (unless you build in deterrents such as maximum retries etc.) If your API is for a game or basic business data then there should be less attraction for a hacker to spend the time on it.
Does your server support HTTPS - often you need to pay extra for a HTTPS certificate or you have to use a shared once which give you a subdomain on a shared HTTPS domain - i.e. https//your-site.your-hosting-provider.com/. You need to check this perhaps.
UPDATE 1: Your problem appears to be with your server and not with your program. Check out this blog post for information about how to set up HTTPS on your Tomcat Server. You need to do this before you can use HTTPS from your Spring application - looking at your code, there doesn't seem to be a problem other than your server.
Also try this.
UPDATE 2 Once you have access, you will then need to trust the certificate on the Android device (or your Java installation if you were making a desktop/web application). It needs to be trusted because you created it yourself rather than a CA authority. See this answer: Trusting all certificates using HttpClient over HTTPS (Not the part about trusting all certificates - this can be dangerous).

Android HttpClient reactive authentication

I am trying to set up an Android app where I can access URL's behind arbitrary proxies or HTTP authentications. That is, the app won't know immediately if a URL needs authentication and will repond to an authentication request by asking the user for credentials, the same way it does for the Android Browser.
I recently worked out how to request user authentication for a WebView, responding to authentication requests from the browser, bringing up a dialog, and advancing the user to the destination page. I am looking to do the same with HttpClient.
The basic process, as I see it, is to:
Perform the request via HttpClient.execute.
If not 401 or 407 with proper headers, trigger a "done" callback.
Otherwise...
Pop up a dialog asking for the username and password.
Set the http credentials in the HTTP client via HttpClient.getCredentialsProvider().setCredentials.
Return to step 1 until the the user clicks cancel or the server gives up. In that case, trigger a "failed" callback with the last response received.
Am I on the right track or has someone already implemented something similar? I would hate to be reinventing the wheel on this.
You should try the authentication example on the apache site
httpclient.getCredentialsProvider().setCredentials(
new AuthScope("localhost", 443),
new UsernamePasswordCredentials("username", "password"));
The direct link to the java file is http://hc.apache.org/httpcomponents-client-ga/httpclient/examples/org/apache/http/examples/client/ClientAuthentication.java
The reactive approach described above did work. Responding to an arbitrary 401 or 407 request is effective with the caveat that you need to suppor each authentication scheme you expect to encounter so something like UsernamePasswordCredentials won't work for NTLM.

Rails Routes and Android mobile HttpGET and HttpPOST

I have a RESTful rails backend where http requests(GET, PUT, POST, etc.) have much to do with controller actions (index, new, create, etc.)
I am building an android app, and I built an api_key controller that assigns all users with an api_key where from the mobile app, every request sends this api_key for verification.
Every request from android to rails has params[:api_key] for verification and it works.
Up until now, I have used both HttpPost and HttpGet, but I know that GET is insecure because it sends the parameters in the header. I don't want someone to sniff the api_key in the header when I send HttpGet requests.
Then, is it possible to simply use HttpPost even in controller actions that generally require GET requests?
Thanks
Using the POST HTTP method does not make the data any more secure, if someone intercepts it then they can retrieve the API key whether it is attached to the URL or in a form.
If you are worried about security, then you may want to think about using HTTPS or some kind of secure authentication system.
With rails the method just determines where rails will route the request to. As long as the request ends up in the right action, in the correct controller then rails will provide the key in the params hash exactly the same whether it is attached to the URL as a paramater or in a form.

Post an image from Android client to Rails server without triggering InvalidAuthenticityToken

I'm building an Android app that runs off of a rails server. At first, when I tried to post simple String data to the server, I ran into an InvalidAuthenticityToken issue, but realized that I can bypass the authentication by setting the content type to "json"
HttpClient client = new DefaultHttpClient();
HttpPost post = new HttpPost(Constants.REST_HOST + "/add_comment");
post.addHeader("Content-Type", "application/json");
The next step was trying to get upload profile picture working. However, when I tried uploading a photo via a MultipartEntity post, setting the content type to "json" causes the following error
StandardError (Invalid JSON string):
but not setting the content type brings back the InvalidAuthenticityToken exception. What's the correct way to post an image to a rails server from a foreign Java client?
ActionController::InvalidAuthenticityToken
(ActionController::InvalidAuthenticityToken):
Based on Jesse's suggestion, I ended up using
protect_from_forgery :except => :upload_avatar_pic
to disable authenticity check, but only for a specific function, so checks for browser requests are still validated.
You can disable authenticity checking on API non-get calls from non-web clients. You can do this in a before filter
class ApiController < ApplicationController
skip_before_filter :verify_authenticity_token
def create
#or whatever
end
end
The problem solved by Jesse Wolgamott said, but the page show "You are being redirected" message when I submit the form (Update,create,show). In before that the page redirected correctly. I am using rails 2.3.8.how to resolve this?

Categories

Resources