Need clarification on the proper way to Authenticate (Android app) - android

We have implemented a Backend Server and a DataBase, with RESTFUL API. We have an Android App that can ask the server to send certain data back.
We want to implement an authentication system on the Android App.
The team suggests that I use Spring and OAuth, but I personally have no experience with those, and am not exactly convinced about the necessity of this approach.
Other friends suggest using FireBase to authenticate the users.
Could I avoid using OAuth/FireBase and simply store in the Server's Database the user's account name and its corresponding hash-salted password, along with the salt? Every request sent from the client would contain the account's name (which could probably be a unique ID generated by the server on the very first request, and saved as a SharedPreference in the phone) and the password in clear. The transmission of the request being done via HTTPS protocol (thus using TLS/SSL), the password in clear would not be revealed.
What are the possible flaws to the suggested approach in the last paragraph? And if it is a flawed approach, considering we already are using Spring for the Server (Backend), should I go for FireBase or OAuth ?
Additional context:
Bare in mind that this is the very first largish-scale project that I have been working on (it counts as a 3-credits University course). We are 3 on the project. I'm studying Computer Science but I do not necessarily have a great grasp on all the systems we are using or plan on using.
We are creating an app which allows users to view on a map alerts published by certain databases (we are currently focusing on meteorological alerts) in real-time. We want to be able to implement a login system so that people can receive notifications despite the application being closed (we are allowing users to "subscribe" to areas on the map, to specify the regions they want to receive notifications for).

OAuth, or better OpenId Connect, is a protocol, while FireBase is just one of its' commerce implementations. It's always better to follow a standard where possible than to implement your own. To see the full list of the certified OIdcC implementations look at the OIdC site, and I see at least MITREid Connect project related to Spring. I think your custom solution will work for your custom case, but only until you think about any extensibility such as Google auth or accessing some 3-rd party API.

Related

Least invasive way to uniquely identify Android user

How can you uniquely identify a user who has installed your app so that:
You will know it is them if they delete and reinstall your app;
You will know it is them if they install your app on a second device they intend to use simultaneously?
Just as an example, I see that the Netflix app will automatically link to your desktop account without any user interaction. I'm guessing that they use accountManager.getAccounts() or similar method, because they also require the GET_ACCOUNTS permission. But of course that permission is marked as Protection level: dangerous. Is there any technique to do this that is less invasive or potentially alarming?
The key to answering this is to be both simple (for the user) and minimally invasive. Android provides heaps of ways to identify users and many of those ways involve piercing a user's privacy, and if that is the only way, I will do what I do now (optional email registration). I just want a way for my app to know if a user already is registered in my system across installs without having to interview the user (username/password, email address, third-party OAuth, etc).
My main reasons are:
I don't want support requests from users who orphaned their content after a reinstall; and
I don't want to host lots of orphaned content.
Have a look at Firebase Authentication. It's quite seamless and does not require much effort to incorporate. Also it does not feel intrusive or cumbersome to the end user.
Here is a video tutorial by Google.
EDIT:
In case your users are sure to have a cellular device with a phone number, you can use AccountKit. It is also what they call OTA (One Time Authentication). AccountKit uses just the users phone number to verify and validate users.
EDIT:
Firebase Authentication now features 'Phone Verification' which is similar to AccountKit mentioned above. Both are good services. However, Firebase phone verification lets you make your own UI from scratch (which means a lot better control than AccountKit). Also, if you don't want to make your UI, you can always use FirebaseUI
i have implemented something that seems little similar to your thing by push notification , i can get error if user uninstalled my app(and from the registration id i get the user) , and if he re installed he obtain a new registration id , and try to get the user UUID for different devices
I think the simplest way would be using UUID and storing the hash on sharedPreferences. You should generate the UUID as earlier as possible in your app.
sharedPrefs = context.getSharedPreferences(APP_SHARED_PREFS,Activity.MODE_PRIVATE);
if (sharedPrefs.getString("YOUR-KEY-TO-THE-UUID") == null || "".equals(sharedPrefs.getString("YOUR-KEY-TO-THE-UUID"))){
prefsEditor = sharedPrefs.edit();
prefsEditor.putString("YOUR-KEY-TO-THE-UUID", UUID.randomUUID().toString());
prefsEditor.commit();
}
I think that the best way would be implementing login with Google or Facebook. This is quite seamless for users, safe enough (as Google and Facebook considered trusted), you do not need to implement your email registration and you will have identity across devices.
If your app is Android only and you'd like to provide identity without any account creation for the user, I believe using Google Account name/id is the best choice (Accessing Google Account Id /username via Android) since you have to use Google Account on Android phone (unless you root it, delete Google Play Services etc).
If you'd like to only address the first point of your question (identify after reinstall) there's a Device Id -Secure.getString(getContext().getContentResolver(), Secure.ANDROID_ID);
though it's not 100% reliable (f.e Factory Reset resets this value)
The standard for achieving this sort of functionality is through the use of JSON web tokens (JWT) in conjunction with standard restful api traffic.
Assuming your android application interacts with a RESTful api for all crudlike operations and business logic, then using a JWT as an authentication identifier to your api can work quite well. You can embed information in each JWT allowing you to identify whatever you like (the user id in the database, the device id of whereve the user logged in from, etc). A JWT is essentially a datastructure allowing you to store information to be used by the API.
Some basics for how this works:
Getting the JWT into the app: A user logs in to the application using their username/password. The
api then returns an encrypted JWT to be used by the client for all future requests. Don't try to do
the encryption yourself. Any language that can handle serving an api
will have libraries for this.
Using information in the JWT: The JWT is itself a datastructure. For example, it might look like this:
{
user_id: 1,
device_id: 44215,
device_os: android,
}
Your api will decrypt the JWT when it is supplied for
authentication via the request header, and then have that information available in the
context of the session.
If you provide the language used by your api then I might be able to recommend a library.
I will conclude by referring to the final requirement you submitted which states essentially that you do not want to have to interview the user across installs. If I understand your meaning, that you want a user to be able to simply install the application and begin using it without supplying authentication credentials, then there is no way to achieve that securely. You might be able to come up with a hackish way to get it to work, but it will be fundamentally insecure.

Correct way to implement anonymous authentication for an application?

I'm looking for your input in authentication to a rest api related question.
Now Imagine the following scenario:
I have an android app that wants to use resources provided by an public API called MAIN_API (which i have no control over) that has a universal API key. The API key grants access to risky actions such as deleting records.
Now i want to allow the users of the app to have a very limited access to the API resources, but i want them to be able to use the application anonymously ( no credentials of their own).
I figured that the best way to approach this is to have another server that would contain the API-key and would provide the means for the limited access for the MAIN_API (for example PROXY_API would only call simple query endpoints). The actual mobile app would call this API. Call it PROXY_API for the purpose of explanation
Do you think this approach is enough to stop malicious usage of the MAIN_API? Do you think it would be beneficial to generate some sort of application credentials getting an access token from the PROXY_API?
To provide basic authentication to a web service is quite simple and will depend on the technology stack you are using on the server.
I'd recommend that if you need to both grant users and client applications access to resources to use an authorization mechanism such as OAuth. There are Opensource OAuth server implementations available. Though the OAuth server is a standalone component, securing your resource server to check authorization against the actual OAuth server may depend on your technology stack.
If you are not very knowledgeable about security, and want to control access to your API/Webapp using OAuth, I'd recommend you a service like Stormpath, Auth0 or 3Scale. They first two offer free accounts and can help you kick start your product.

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).

Using OAuth/OpenID across a web/mobile app

I'm currently designing a service that will be half web app, half android app. Each user will need to be able to log in from either the android app or the web app, using an openID account. I'm hoping to target Google first for easiest integration with Android, but I'll also need some OAuth stuff later so that I can integrate with Google contacts.
The bit I'm having trouble with is how to authenticate users. The structure I've planned is that the server (probably using web.py, although that's flexible right now) serves data for the client in JSON, whether the client is the javascript browser client or the android client. However, each call needs to make sure the client is allowed access to that data.
What would be the easiest way to standardise this across the platforms?
Should I be using a session system to authenticate after logging in? Can that be made to work from an Android app? Otherwise, should I simply authenticate with google for every request?
When authenticating from the app, where should the authentication happen, through the server or straight from the app? Where should the auth token be stored in this case? (I'm assuming for a straight webapp the token should just be stored in a table in the user database?)
Sorry for the barrage of questions, but I haven't really found any resources online that clarify these issues very well.
As long as you are using HTTP, the platform doesn't matter. You can use the same form of authentication and/or sessions. The only difference would be that on Andorid you might be able to get an authentication token using the platform's AccountManager, without having to type the username and password in Google's login page.
There's a subtle difference between Authorization (OAuth) and Authentication (OpenId). Make sure you know what you are doing.

How to interact with web application from android application?

I have a Java based web application which is developed using JSP/Servlets running on Tomcat server. This application is developed for customer support. A customer can directly login to the application with his credentials and raise any complaints reg. a specific product. He can also view all the complaints he has raised and their status. Also he can add comments to the complaints and also close them when he desires to.
Now I would like to develop an Android app where a customer can login with his credentials and do same operations as he used to do in the above said web application.
I have basic knowledge on Android and good amount of knowledge in Java. Can someone help me with some guidelines or sample source code to develop such kind of application. In particular after authenticating a customer with his credentials from an Android activity by sending HTTP request to the web application, how do we keep track of the session for that customer in order to display him the complaints raised by him or allowing him to add comments to his complaints in next activities (screens). To put it simple how to maintain sessions?
Thanks,
You question is pretty specific to your application. How you maintain a session with the server is pretty much up to you, but you can think of it as implementing the relationship between a web browser and a web server.
After your user logs in, the client should receive some kind of token from the server (similar to a cookie). All subsequent requests will pass along that token to authorize the user, so you'll have to persist it on the device. Your server will have a mapping of tokens to users.
I would recommend looking into OAUTH2 and maybe taking a look at some well used APIs like Twitter and Foursquare for some ideas about best practices.

Categories

Resources