Is OAuth good choice for RESTful API in this SaaS scenario? - rest

Is OAuth sensible to use when the user account info (user id's, passwords, roles, etc) is going to be maintained in our own back-end and when there will not be any sharing of resources with other sites? Or is sharing the whole point of using OAuth?
Background:
I'm working on developing an enterprise SaaS product and we are creating a RESTful API to be used by our front-end applications. Consumers of the API will be browser and native smartphone (iOS & Android) applications that we develop. Since we'll be supporting multiple client types, it makes sense to create a RESTful API that all our client apps can consume.
Naturally we need to secure this RESTful API. We are considering authenticating using HTTPS / Basic Auth but we are aware of some of the well known drawbacks to this approach.
Some quick research shows OAuth is highly recommended. But most of what I find with OAuth is in the context of authorizing web sites to share information on behalf of the user.
Any info if most welcome.

Good question, and we're having a good discussion on this over at API Craft:
https://groups.google.com/group/api-craft/browse_thread/thread/b87fd667cccb9c00
Here's the answer that I posted there:
I think this is a good use case for OAuth, actually.
First of all, with OAuth your mobile app can store an OAuth token on the client rather than the user's "real" password. So, you can have the app automatically "log the user in" by getting an OAuth token without having to store the actual password on the device. If the user loses the device or if it's compromised somehow they (or you) can wipe the OAuth token without requiring that the user change the password and blow away other things that they might be doing with your API. There are similar examples for an Ajax-style web app but it depends more on the specific way that you build the client.
Second, the OAuth token is associated with a unique key that identifies the app that is making the API call, and that in turn identifies which developer built the app. That gives you options like tracking usage by application, turning off an application that might have been compromised without disabling the whole API, and if you ever want to open access to third parties or partners who build apps for your API, you can offer different levels of service to other customers.
Third, your IT security people will be happy if you tell them that you never store a password on the user's mobile device or stash it somewhere in their browser.
Fourth, you have the option of browser-based login for the mobile app. That means that the mobile app will never see the user's password, and also that if you want to implement two-factor security or something like that, you can do it in the login screen without changing the mobile apps. Now, the downside is that the user sees a browser window pop up. That's why OAuth gives you a few different ways to get an access token for an app, so you can choose whether you need to have browser-based login or have the user enter their password directly in the app.
Fifth, how do you know that your API will only ever be used by your own apps? If you use OAuth now then you will have an easier time making that transition later.

Yes, this is a very good fit for OAuth. You can still use HTTP Basic over SSL during the handshake for authentication. The output of the OAuth handshake will be a token which can then be used to consume the API. This way, the application does not need to store the credentials and tokens can easily be revokes with minimal user impact.
OAuth 2.0 defines a number of different grant types for accommodating different situations. It sounds to me like the 'implicit' or the 'resource owner password credentials' are the most appropriate but you may want to consider each carefully.
You should not implement this directly in your API but use infrastructure to delegate the OAuth support and token management on behalf of your SaaS API instead.
Take a look at
http://www.layer7tech.com/blogs/index.php/oauth-token-management-2/
and
http://www.layer7tech.com/products/oauth-toolkit
Hope this help,
-fl

I implemented an OAuth for Django nonrel with piston to expose my APIs to consumer. There are a number of kind in OAuth(2-legs 3legs).
Generally, supporting OAuth is quite a bit challenge. You have to obtain the request token, authorize it, store the access token to sign every request you want to authenticate.
Advantages
- You don't have to send username and password everytime, secure.
- Enable third party to consume your app.
Disadvantages
- Make 2,3 round trips to authenticate.
- Complicated to implement it by yourself.
I'm pretty sure that you can find a number of library that allow you to:
- Expose your Api and support OAuth. E.g Django piston.
- Sign your requests by adding headers to them. E.g Oauth-signpost.

OAuth is only a token and the requesting App will issue one. You can read more in pingidentity.com where there are several webinars on this topic(cloud identity and user provisioning) as well.

Related

Spoofing facebook app ID

Following up on the design outlined in Design for Facebook authentication in an iOS app that also accesses a secured web service, and specifically the concern listed in https://stackoverflow.com/a/12912616/5154090: what would be the mitigation?
Specifically, I have a web server that exposes a REST API which is consumed by a mobile app. I'd like users to authenticate to the server (via the app) using Facebook.
Now, an apparently common flow is for the app to redirect the user to Facebook, where they will login with their credentials. The app will then get a token which it will send to the server, and the server will validate the token using the graph API.
But how can the server make sure that the token really came from the app? Specifically, what's to prevent a malicious app vendor from re-using my app ID? After all, the app ID is hardcoded into the app and can therefore be extracted and used by a malicious app. If users log into that malicious app with Facebook, then the malicious vendor can get tokens with my app ID and can impersonate users of my service.
How can one protect against this?
To summarize for anyone else who happens to contemplate this - there is indeed no way to prevent the client ID from being spoofed. This is one reason that developers are discouraged from using the OAuth implicit flow in native apps as pointed out by Andre D in https://stackoverflow.com/a/17439317/5154090:
the use of the Implicit Flow with native apps is NOT
RECOMMENDED.
(see https://datatracker.ietf.org/doc/html/draft-ietf-oauth-native-apps-09#section-8.5).
In practice, if anyone mounts this attack, then the user will download App A (a malicious app) and will then be asked to authorize App B to make actions on their behalf. As far as I can tell, this is generally the only indication that an attack is taking place.

Build a REST API available to authorized apps only (like Facebook) with Laravel

I'm building a REST API with Laravel and now I have an URL like
api.example.com/posts/3/comments
Now I'm wondering how to secure this API because as it's done now, anyone trying to make a GET, POST, ... request on this URL will get positive results.
I want this API to be available to authorized apps only (like Facebook API). For now, those apps are just my website and my iOS app.
I'm thinking about creating a table applications to store application's keys. But I don't know how to authenticate an app without publishing it key (which is obviously insecure).
Any suggestion? Thank you.
I would recommend that you use something like JWT. Using it, you create and store a token locally on the device, then every time someone makes a call to the server, you check the token and make sure that they are who they claim to be. You can store tokens for expiration if you like. They're typically used in stateless apps, so you will need to move away from the concept of a server session. You can use Middlewares to filter HTTP requests entering your application.

Using Google as the Source IDP

Is there a way of passing username/ password to Google Apps IDP and get a response as to whether a username/ password pair is correct?
I know I can use OAuth for authorization and access user data but note that I want to check if his credentials itself are valid. OAuth for sure will not work for me. I need a way to directly query Google Apps' IDP particularly not to use it and access something else.
I wish to use this to customize the Google's standard login page itself. OAuth doesn't allow me to do that.
Short answer: no.
Google actively tries to prevent the scenario that you describe because it would mean that Google users hand over their Google credentials to your application, aka. phishing.
That precludes branding of the Google login pages as well since it would make it harder for users to verify that they actually type in their credentials on a login page provided by Google.
As said in the other answer, Google Signin with OpenID Connect (built on top of OAuth 2.0) is the standardized way to offer users login to your application with their Google account.
Google (Apps) accounts can be used as an OpenID identity provider. By implementing your app as as a relying party, you could authenticate your users based on their Google accounts. Much like stackoverlow Google login: http://code.google.com/googleapps/domain/sso/openid_reference_implementation.html
With SAML SSO, Google acts as a relying party. While its possible to use provisioning API and clientLogin, this is not supported and is possibly against Google Apps ToS.

Is it possible to send a request to the Facebook Graph API from client side without exposing our access token to the public?

My question is related to, but not exactly, this question.
I am currently working on a business directory Web site (similar to Yelp), in which businesses have their own pages. Let's call this app DIRECTORY_APP.
Businesses might want to have their latest Facebook status update shown on their pages hosted on our directory. Let's pretend we have a business named BIZ_1. The assumption is that those pages are public pages.
Apparently the Facebook Graph API can be used for this purpose. So I can send a request to Facebook to retrieve the latest status updates for BIZ_1:
https://graph.facebook.com/BIZ_1_PROFILE_ID/posts?
access_token=DIRECTORY_APP_ACCESS_TOKEN
&callback=callbackName
However, if I use this from the client side, our Web site's access token will be exposed to the public, so this is not a reasonable solution.
Now in the aforementioned question, Anatoly mentions that we can retrieve the access token by sending this request first:
https://graph.facebook.com/oauth/access_token?
client_id=YOUR_APP_ID&client_secret=YOUR_APP_SECRET
&grant_type=client_credentials
However if someone inspects the Network log, this will also expose our Web site's access token (is this correct or is this a different type of access token?). This solution also exposes our web site's app secret (is this safe?).
So to summarize, what's a safe way in which I can retrieve the latest status update of a Web page from client-side without asking the browsing user to first log in to Facebook?
I can retrieve the latest status update of a Web page from client-side without asking the browsing user to first log in to Facebook
You cant do that without login.
And I guess access token is not exposed.
Maybe the smart trick here is to use a social plugin. The Like Box will do what you want, without any issues. But, it's not greatly customizable. Even so, it's possible to get it looking nice on a page!
It also skips any login issues you mentioned.
I found the answer after some Googling. In short, the answer is no.
And here's an excerpt from Facebook:
Security Best Practices
App Secret and App Access Token
The App Secret is used in some of the Login flows to generate access tokens and the Secret itself is intended to secure usage of your App to only those that are trusted. The secret can be used to easily create an App Access Token which can make API requests on behalf of any user of the app, which makes it extremely important that an App Secret is not compromised.
Therefore the App Secret or an App Access token should never be included in any code that could be accessed by anyone other than a developer of the app. This applies to all methods of code that are not secured like client-side code (such as HTML or Javascript) or native apps (such as iOS, Android or Windows desktop apps) that could be decompiled.
We recommend that App Access Tokens should only be used directly from your app's servers in order to provide the best security. For native apps, we suggest that the app communicates with your own server and the server then makes the API requests to Facebook using the App Access Token. For this reason, if your 'App Type' under Advanced Settings in the App Dashboard is set to Native/Desktop we assume that your native app contains the App Secret or an App Access Token in the binary, and we do not allow calls signed with an App Access Token to proceed. The API will behave as though no access token was provided.
If your App Secret is compromised, you should reset it immediately in the Basic Settings of your App Dashboard.

If I use Facebook for authentication, is regular HTTP fine?

Can the Stack Overflow community sanity-check this for me?
I am working on a project that involves two components: an iOS app and a mobile website. It's for a product that will interact pretty heavily with Facebook. The website is hosted on Heroku.
From iOS land, my intention is to use the Facebook iOS SDK for authentication and then hit the web API with the user's access token at https://[myappname].herokuapp.com. Since Heroku offers piggyback SSL when using the herokuapp.com domain, and the user won't be seeing this URL anyway, I figure that's fine. And this way the request is encrypted, so the access token should be safe.
From the mobile website, users will log in using Facebook, at which point my understanding is that the access token will be in their cookies, which my server can then access without having to exchange it back and forth with each request. By this reasoning it seems to me I can just stick with regular unencrypted http:// URLs for the website (and therefore use my custom domain name without having to pay a monthly fee for Heroku's SSL Endpoint add-on).
Does this all make sense? I will be the first to admit my understanding of a lot of this stuff is in serious need of an upgrade. But for now I'm just looking for someone who can tell me, "No, you're totally overlooking/misunderstanding XYZ" or "Yeah, this is how it's generally done."
Facebook advises that you should not take a dependency on their cookie format. They have stated that the cookies are "an implementation detail" that they may tweak at any time with no notice given. You should not directly access the token or other user info directly from the cookie. I personally have had some bad experiences trying to get user information directly from the cookies, mostly due to timing -- they were not always there or updated when I expected them to be.
Client-side, you should either get the access token from the Javascript SDK via FB.getLoginStatus or other method that returns the access token, and then post it up to your server. This should really be done using ssl otherwise you are susceptible to network packet sniffing where a black hat could grab the token and be able to use all of the privileges the user granted your app.
There is also a server-side option as well which hits at ssl endpoint on Facebook's servers to return an access token.
References:
"Cookies are an implementation detail": https://developers.facebook.com/blog/post/624/
Authentication docs: https://developers.facebook.com/docs/authentication/
Website login via Facebook works totally fine via HTTP.