User authentication methods for REST api project - android

My web server has a REST API. I need to add user authentication to my app, and my thought process behind it is this:
Get the user's username and password from the app form
Encrypt the password and Base64 encode both the username and password
Send the data to the REST API over HTTPS
Web server verifies credentials, returns errors or success
Is this secure? I see a lot of mentions of OAuth2. What is it? What does it do better than my process?

The fact that you used the word "encrypt" for the users password instead of "hash" demonstrates you have fairly limited knowledge about this. This will almost certainly result in you messing up your authentication procedures somewhere along the line and put your users private information at risk.
A really important point about OAuth2 is that it can be used with many existing third party providers (Google, Facebook, Twitter, etc) with minimal effort from you.
You don't need to do anything to store credentials or even authenticate users. The third party takes cares of all of this and simply provides the client with a token (long random string) which is then passed to your server. Your server then talks to the third-party server to make sure the token is valid (and gain any info you need, like the users' name, email address or other information).
You really should consider using it if you can. The big companies put a lot of effort into securing their authentication methods and you gain all of that by making use of it.
A final nice point is that users don't need to create and remember credentials for (yet) another account.
Google has some docs to get you started and includes an OAuth playground to test how it works in practise.

A very basic explanation of OAuth2 is that the user will log into your system, with it encrypting both username and password before sending it, then if it gets authenticated, it will send back a token to the user.
Thereafter, whenever the user tries to contact the web server, it will send this token along with each API call. This is how it makes sure that non-authenticated people can't access your web server.
So basically your current method includes parts of the OAuth2 standard, but not the most important part (The token).
In your situation, how would you stop non-authenticated people from accessing your web server? If the project is small, then the risk of this is not that large.. But for larger companies, this is a real threat that needs to be dealt with.

You should really try to understand the difference between encryption and hashing before providing an authentication portal for your users. There are many different hashing algorithms you can use. I've personally used BCrypt in the past and I have a related SO Question about it as well. You can find implementations of pretty much all the popular algorithms in pretty much all the major high level languages these days.
Obviously if you don't want to do all that you can use an OAuth provider, who will take care of all the hard bits like storing the passwords securely, protecting the database and all the other security aspects for you. There are many reliable OAuth providers, Google, Facebook, Yahoo, etc. etc.
One thing to bear in mind would be the environment in which your app is hosted. OAuth does depend on having a connection available to the OAuth provider's servers every time a user wants to access your app. So, if you are behind a corporate firewall or similar which may block access to websites like Facebook, this might be a big problem.
I personally prefer token based authentication for my API projects. If you're not familiar with token based authentication you can read this SO Question and this link.
The general concept behind a
token-based authentication system is
simple. Allow users to enter their
username and password in order to
obtain a token which allows them to
fetch a specific resource - without
using their username and password.
Once their token has been obtained,
the user can offer the token - which
offers access to a specific resource
for a time period - to the remote
site.

Related

Secure an API for mobile apps call

I've been doing a lot of search about secure my api for mobile apps for Android or IOS.
Almost all examples tell user provides an user id and password somehow in a exchange for a token.
But how to prevent someone else to consume my api without my consent?
Face the following scenario:
I expose an API,
I develop, then, an app for android to consume it,
I develop, then, an app for IOS to consume it.
Other developer performs a rev. engineer in my app, creates his own app and starts to consume it without authorization.
How to prevent that?
Short answer: you can't.
Little longer answer: If you know what you are doing you can always reverse engineer a given application and use its api. You can only make it more difficult and time consuming, using authentification via tokens and device ids or usernames is a good first step. Apart from that: why would you want to close your api to outsiders? If your server code is written well there is nothing to worry about.
You can maybe secure your API on a legal basis and sue developers who use it, but that is a completely different topic.
Some clarification regarding securing the API and securing content via the API. Assume you create a server where you can send user/password and receive a token if that combination was correct. For the account-page you send said token over and the server verifys that that token is valid and returns your account page. You secured the actual content of the API. That is obviously very possible and almost a must-have unless you have no user-specific data. But still everybody can send the exact same initial request from their custom app, sending a user/pass and again receive a token, etc. You cannot really prevent the request itself or even determine that it was not send by some service not authorized by you. You can send some hashes along the request to add some security by obfuscation, but since your app has to compute them, so can the reverse engineer.
Yes, login api are open but they return a token only on successful match in your database. You should focus more on security of your data than unknown hits at your api.
SignUp API can be used for creating a user, and login for returning token of that user. Only if malicious developer has credentials, then he can access tokens and auth APIs. There is also something about DDOS attacks so you can maybe write logic to temporarily block IPs where hits frequency is high.
You can also store device ID of signing user, which seems idle for your scenario. Entertain hits from that deviceID only. Similarly, user can add more devices with their credentials. I think even Google does that (generate alerts if user creds are signed in from new device and add the device to list if user confirms). Hope this helps.

Storing API key on mobile device

I've read many, if not all, answers to previously asked questions about the same topic, but questions themselves are not exactly about my case.
I have an OAuth 2.0 server running. It has an endpoint that provides access tokens to users. Programs and websites requesting the access token may or may not be owned by me, in other words, I may add a tool for website users and locate it on the same or neighboring website and my users may create an app and with their API key request access to user's data. Now I am developing the app that will operate user's data.
I realize that storing the API secret on the device is not a good solution. I have read about creating an end-point to which I make request directly from the app and then the endpoint makes API requests, but the endpoint will have to exist on the same host and probably server as OAuth server.
Is there a way to authorize mobile application to access user data when I am in controll of the application and the OAuth server? Should I create a separate end-point? Should I pass it device ID and/or any other information?
P.S. I know that plain old authorization would work here, but then what if some user wants to create his own mobile extension (not allowed currently for security reasons)? Also, current system has a button that is recognized by many people and they know what exactly will happen after clicking it. With the app, it may be an issue when the user sees a login dialog instead of the "Login with *" button. I really hope there is a clever solution to this.
Your concern is spot on. Your API Secret should not be stored on the device.
However, I am not sure why you would be concerned to build a separate endpoint, since OAuth 2 has a authorization flow for these use cases.
https://www.rfc-editor.org/rfc/rfc6749#section-9
In your use case, I'd suggest using the implicit grant flow to fetch the access token and store that on the local device. There would be no refresh tokens and the access_token can have an expiration date. Of course, the token on the device can be compromised, but the damage will be limited to a particular user and not the entire application.
If this level of security is not acceptable, then you can look at splitting up your API Secret in different parts of your app and then assemble it at run time in your app.

secure a REST API for use by Android clients

We're developing a JSON REST API in Rails to be consumed by an Android application, which we are also developing. Is there any way to secure the API such that it can only be used by our specific Android application?
The API is read-only, and does not involve any kind of user-related or otherwise sensitive information. But to the extent that is reasonable we'd like to prevent abuse and restrict its use to only our app.
I could easily add an authentication token to the API and distribute it with the app, but:
We'd probably have to move the API over to SSL, if we use BASIC auth.
It's probably trivial for a determined person to open up the Android APK binary and uncover the auth token anyway.
The situation seems analogous to a café posting their WiFi password on the shop counter- you have to give the secret out to everyone who wants to use your service, so it almost seems pointless to have it in the first place.
What's the most reasonable approach to take?
Wanting to secure a probably public undocumented API so it can only be accessed by one application, means you want to stop people from using your API who are determinate of using your API.
Meaning people who would try everything possible to use your API.
If this is not the case adding a Auth token won't be trivial but at least a big stepping stone for people who stumble upon your API. And not a very bad idea to implement this.
Because this authentication isn't user based but application based and you don't want authentication to rely on user input. The request must be purely done so by the application.
Meaning you will have to do so anyway(adding hardcoded token). Only you make it very very difficult for a determined person to uncover the access and request tokens and the methods.
It depends on the situation, but I would go for the SSL and hardcoded token.
Some extra security:
Release an access token to the application which only need to send a
request token periodically. Meaning less chance people intercept the
hardcoded request token, but a session based access token which
expires. Maybe just do this once for every application install.
Encode this request token before sending it through the air. Meaning
people have to decompile your app.
Obfuscate code (make it more difficult to decompile).

Android APP that consumes a webservice how to authenticate users

I'm developing an android app that consumes a webservice that I will develop too (I'm thinking in using a RESTFul webservice)..
and I want to secure the connection between the app and the server but I need to authenticate users too..
My problem is in the last part, to secure the connection I think the best way to do it is to use SSL (https), am I wrong?
I don't know what's "the best way" to authenticate users, to make sure that a user cannot consume the webservice as another user..
I have some ideas, like using a authenticate(login,pass) method on the webservice that returns a token.. And for any operation that requires authentication the user would need to pass that token as a parameter.. The thing is, is this a good way to do this? whats the most common technique used to auth users in a situation like this?
If a token based auth is a good idea how should I generate the token?
Sorry for this long text..
Any help will be usefull
Thanks
Make sure you understand a trendy standard like OAuth before you go down that path. Most OAuth flows are centered around a user logging in to your server through a web browser. This can lead to pretty bad user experience for a mobile app. The standard does allow for alternatives. Here's a decent introduction.
You could also use an existing identity provider like Google, Facebook, Twitter, etc. instead of implementing your own authN/authZ. On Android, you can ask for a Google auth token using the AccountManager. This usually works because the user needs to be logged in to their Google account to access the Android Market. Anyway, this will prompt the user to grant authorization to your app. You could then use the Google auth token to login your user to your service with your own token. The login would essentially be your server verifying the Google token is valid (by contacting Google's servers) and then issuing its own token to be used for calls to your web services. If you don't like Google, you could use the Facebook SDK, etc.
As for what to use for tokens... The OAuth spec has stuff on that as well. You could do something as simple as a random string or something as complex as encrypted SAML assertions.
You should implement a token based OAuth, which will require the users to log in once, and then permanently have access.
You can use Google App Engine which already provides user authentication services for you (your Android users most likely already have google accounts) But this is only one of many options.
You can also look into Amazon's Identity Access Management (IAM) which will allow you to manage the users who have access to your web service, and authorize them accordingly.
I think the best way to do it is to use SSL (https), am I wrong?
This only prevents certain types of malicious use, but not everything. There is still nothing to prevent people from accessing your database on the phone, and retrieving credentials that way.

Securing communication from android to a web service

I'm a relative newbie to web and mobile development and especially to security so obvious answers are still appreciated.
I want my android app to be able to log in to a simple web service with a username and password.
What's the best way to send this information securely and keep the user logged in for an entire session?
Do you control the web service? If not then you will need to use whatever authentication mechanism the web service provides.
If you're writing the web service yourself, you have a lot of options.
The simplest is to just send the user's username and password via SSL with every request as a HTTP Authorization: header. The downside here is that you need to keep the username and password stored on the device. That being said, because of the way Android's permission system works, there's very little risk of an attacker stealing credentials off of the device, provided the user hasn't enabled root access.
If you still want to avoid storing the password in plain text, you can send the username/password once (again, using SSL), have the server return an encrypted authorization token, then send that token in place of the user's username/password. See Google's ClientLogin for an example of this. An attacker could still steal the token if they have physical access to the device, but at least the attacker can't use that to gain access to any other sites that use the same password.
There's other options out there as well, like using challenge/response to prevent the server from ever seeing the user's password, using OAuth to provide a common authorization API, and so on. It all depends on what your particular requirements are.
A friend and I are looking to do this same thing, and I think that we've settled on storing a web service key unique to the user on the device, and using that for authentication rather than storing un/pw (this is the second method provided by Trevor above). You'll need to make sure to provide for a means for getting that key onto the device as well.
You can use a server based random key and local imie based key along with users unique token for making a logic .you can put an expiry time for every key

Categories

Resources