In our application we provide user authentication possibility which gives him additional rights and functions. Now we need to add an ability to login into our application using social networks (Facebook, Twitter, Google+, LinkedIn). We don't need any functions of these networks.
I've read these articles about social networks authentication on Android:
LinkedId
Facebook
Google+
Twitter
All of these networks provide their own Android libraries which handle authentication process. I don't know if I need to use them (they have different APIs and seems to be quite "heavy"). I also found 3d party library which handles all of the needed networks.
Now what I don't know:
After user logs in into any of these networks using appropriate library mentioned above what do I have to send to OUR server to login him into our application? Is it OAuth token (but it seems to be valid only for mobile application which aquires it), SN user id, email or anything else (let's call it access token)?
After access token is sent to the server what server has to do with it? For example aftet successful login through any of SN user tries to use one of the features our application login provides. Each of these features needs server request. So when one of these requests comes to our server does it need to check if access token is still valid or it must just create our user instance once token comes for the first time and later it doesn't need it anymore?
Do I need to store access token locally on device or after it is sent to the server I can forget about it?
How to provide logout function?
Ok, I understand that this question may be not correctly formulated so please, feel free to ask for more info if you need it.
Related
I'd like to a make a mobile app that makes requests on behalf of a user. I understand the following OAuth flow:
Open user in web view to give my app access to make requests on their behalf
When they hit grant access, my server side app will receive a call with an authorization code
My server side app then needs to exchange the authorization code for an access token
My confusion starts in Step 2. Uber makes a request to my endpoint with the authorization code, but I have no way of knowing what user that authorization belongs to. I can exchange it for an access token and store it in a DB for 30 days, but I have no way of getting it back to the user to use to make requests.
One thought was I could have the user sign in to my app with an email address which I could then use as a key to get the appropriate access token from my server app, but I have no way of associating the access token with an email address in my DB table in the first place.
I'm wondering what the best practices are here. How is my mobile app supposed to know what access token to use for a given user?
(I reached out to Uber API support directly, but they asked me to open a StackOverflow question instead)
Obviously this is kind of a broad question and is highly dependent on what type of app you're building, what you want the user-flow to look like, etc etc but I'll do my best to point you in the right direction.
First, the Uber API has the /v1/me endpoint which will return the users first name, last name, and email address, among other things. So one possible flow is that a User opens your app, they then go through the whole OAuth flow, and once you exchange the authorization code for an access token you immediately use it (from the server) to make a call out to the /v1/me endpoint and then use either the users email address or UUID as a key in your database. If you used email address, you could just allow users to login to your app using this same email address and allow the account creation process to just be the OAuth flow.
I'm not a mobile developer, but my understanding of embedded web views is that they can use cookies just like any other browser. In that case, another thing you could use is sessions / cookies. Assuming you have some kind of identifier for your existing users, you could add that as a cookie for your web server and then when your user gets redirected to your web server with the authorization code, the attached cookie will tell you which user to associate the access token.
Finally, the Uber developer platform includes a state parameter in the authorization phase of the OAuth flow as seen here https://developer.uber.com/docs/authentication You could do something similar to what I describe in the previous paragraph, except instead of using cookies you could store the user identifier in the state parameter and it'll be sent back to you when the user re-directs. You can use that piece of information to tie the access token back to a specific user in your DB.
I hope that helps! Don't hesitate to reach out if you're still confused.
Cheers!
We're developing a REST based API that developers would call from their mobile apps, e.g. google play apps.
How can we make sure that the app developer doesn't steal the users user/pass by storing them or sending them to "EvilServer".
If we do not trust the app developers, does a technical solution to this problem exist?
Could one solution be to have our own trusted authentication app on the native platform and let app developers use it to authenticate?
What I would recommend is to first remove the ability for a third-party application to log a user to your service using his credentials, so there is no reason for an app to ask for the user's credentials in the first place.
I would instead provide an OAuth authentication endpoint (take a look at the server-side flow) to third-party developers in order for them to use your authentication service to register and authenticate users in their app. This is interesting because users have to be redirected to your authentication endpoint when they log in, so there is no chance a third-party application can have access to their credentials at any point.
However, nothing prevents the developer of an evil app from creating a fake form requiring the user to provide sensitive informations in order to log them in, such as an email and a password.
In this case, you can do two things :
First, educate your users (e.g when they create their account) not to provide their credentials on any other website than yours. This is typically done by banks and insurance companies.
Implement Multi-Factor Authentication to add another layer of security to your authentication process. Most web companies such as Google or Twitter allow you to require that while providing your usual credentials when logging in, you are still required to validate the login process using an out-of-band medium. They typically achieve this by sending you a PIN code via SMS on your phone that you must input on a web page to finish the login process.
As such, if someone tries to log into one of your user's account, it will fail unless they have also access to the user phone.
OAuth attempts to solve this problem by sending the user off to a provider to authenticate before bringing them back to the original site or app. This is how the "Log in with Facebook" and "Log in with Twitter" systems work.
There's a handy diagram at http://www.quora.com/How-does-Login-with-Facebook-option-work-on-third-party-websites that shows how the requests are passed back and forth.
In the widely known If This Then That app (IFTTT) you can create workflows such as:
If I get an email with an attachment, add that attachment to Evernote.
For this to work you can authorize so called "channels" such as Gmail and Evernote. In practice this means that you need to enter your username and password for for example Gmail, after which the IFTTT app can freely scan the incoming email within.
I now wonder how this system works? Is there a specific API within iOS/Android to allow such interaction between apps with specific triggers upon receiving email, or does IFTTT store the usernames and passwords in cleartext and regularly poll the email boxes (which I cannot imagine)?
Could anybody shed some more light on the inner workings of this process? Any information or tips would be welcome (a description, names of API-endpoints, code examples, FLOSS alternatives that implement this, anything else)..?
It'll vary per provider, but many of them, including the Gmail flow, use OAuth for the authentication part. After authentication, they'll use whatever APIs are provided by each individual service.
The clue with Gmail is the way you're redirected to Google themselves for authentication, and the URL has "OAuth" in it. When I just tried it, the authentication URL was:
https://accounts.google.com/o/oauth1/auth?oauth_callback=http%3A%2F%2Fifttt.com%2Fchannels%2Fgoogle_callback&oauth_token=[REDACTED]&btmpl=mobile
What'll happen is that Google will authenticate your credentials, so they're never given to a third party like IFTTT. Instead, on successful authentication, Google will "call back" ifttt on the "oath_callback" URL provided, and effectively give them a token that will allow access. At any point, you can go and revoke that token (somewhere in Gmail's preferences) to prevent IFTTT accessing your account, so control of your account is always in your and Google's hands, and IFTTT only get the access they're granted as long as the token lasts. (Here are Gmail's auth scopes). Your username and password are only ever authenticated with Google's servers, and never stored by the third party.
As with authentication, how IFTTT monitor and respond to events once that authentication has taken place is up to the specific service's API. In some cases they'll poll, where possible they'll probably register for event callbacks. According to this Quora answer from Linden Tibbets, one of IFTTT's creators, for Gmail they use OAuth for obtaining an IMAP login, then use that for polling.
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'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.