This is an "Is this possible?" question. I have an app for the android phone and another application for the appengine platform. The appengine thing is really just a db of high scores, and the phone app is really just a game. I can, using some json/gson/httppost stuff, send the scores from the game to the db. Now I want to make sure that the scores I have collected come from the game, not some guy, maybe talented at programming but with too much time on his hands.
Here's the question. Can I use google OAuth 2.0 to somehow authenticate that the scores I'm getting come from phones running my game?
I thought I'd do this: I'd use OAuth to get some kind of token from google (from the phone), then pass that token to the appengine database (using a json record), then use the token to get info from google on the user. This could be as simple as an email address. Then I'd say to myself "Well, as long as I get an email address for the user, then I know that the user is using the game, and I can store their score." Does this sound possible? I get the feeling that once I use the phone to get the token from google, it's unusable by the appengine program.
I was thinking I'd use the client_id and client_secret, (and whatever else I needed) that were associated with the appengine db to get a token from the phone, then when I sent the token via json to the appenging program to get the email address, they'd work from appengine. This seems like somehow the google OAuth would know that I was trying to get a token from a phone, and then would reject the whole thing. Then again maybe it would work. They say though that android phones cannot keep secrets (referring to the client_secret).
Finally I was wondering if there was any other easier way of making sure that the score I was recording at the appengine side was truly coming from an android phone running my game? Can I set up my own authentication scheme? How hard is this to do?
Good timing; Google just released a feature will address your question:
http://android-developers.blogspot.ca/2013/01/verifying-back-end-calls-from-android.html
Doing this is a multi-step process, which I’ll outline in full, but
here’s the short version: You use the GoogleAuthUtil class, available
through Google Play services, to retrieve a string called an “ID
Token”. You send the token to your back end and your back end can use
it to quickly and cheaply verify which app sent it and who was using
the app.
With OAuth 2.0 (Open ID connect) you can identify the user that is using your game. It seems that you want to authenticate the app though. There are multiple ways to do this, but you still have to embed the credentials in the app or create some sort of registration mechanism. Generally, as long as your attacker (skillful user) has full access to app code and the device (rooted, etc.), there is not much you can do. The only question is who hard do you want to make it.
Or you can use a third party service such as Parse, and trust that they spend some time perfecting their app authentication mechanism.
Related
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.
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.
I have an app where users can add ratings, and I don't want them to have to register to do it, but I also don't want it to be easy for bots to game the ratings.
Is there a way I can be reasonably (doesn't have to be 100%, but I don't want to use reactive heuristic methods) sure that my users are human? Without requiring any kind of CAPTCHA / sign-in / other action. Normally I would say that this is impossible, but since my app runs on Android I think we can do better than nothing.
Gmail address.
My first thought was to get their gmail address from AccountManager, but I can't see a way to verify that they own that email address - i.e. a bot could just send made-up emails to my server, so I don't think this can work (and I don't want to make them authenticate my app using their google account; they are unlikely to do this).
GCM
My next thought was to use Google's Cloud Messaging thing. I can get a cloud messaging ID from the device, send it to my server, send a random cloud message from the server back to the device, and send that message back to the server. I think this at least verifies that they do have an Android device with a gmail account, which is good enough.
SMS
Of course I could send them an SMS, but that costs money and to be seamless means that I need to have permission to read their messages, which I'd really like to avoid (especially as the rating is an optional feature).
Android Licensing Server
Maybe it is possible to use the Licensing Verification Library to get a signed assurance from Google that the user downloaded it from the market, but due to the nature of my app I can't put it in the market.
Device ID, EMEI, phone number, etc.
Of course I can't use these. Bots could just make them up!
So GCM looks like the best (and only) option. Can anyone think of anything else?
Show some popups randomly and place their close buttons at different place, so user has to close them.
OR
Using drag drop API ask user to drag and drop button into some area on screen and then submit rating. You can randomize placing of button.
There could be multiplaces where you can drag button but you can instruct user to put in the right one.
As you control both sides of the communication, you could do something like this:
Flow
App: Request one-time secret token from server.
Server: Create one-time secret token and a tracking-id and send both to the App, while keeping track of the secret token by using the tracking-id.
App: encrypt the voting using the one-time secret token (see below about encryption)
App: send encrypted message and tracking-id to server.
Server: Find secret token using tracking-id, make sure it hasn't been already used and decrypt the voting using the secret-token.
Encryption
You can use any symetrical encryption technology. A very simple example would be to XOR your message (i.e. voting) with the secret-token on the App-side. On Server-side XOR-ing again with the same secret-token gives the plain message again.
This method is safe as long as your method of encryption is not known to the attacker. If it is known of course he can just simulate the requests the App does, but it would hold true for every method, so you probably should use something better than simple XOR-ing.
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.
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.