Facebook Oauth Code Flow - facebook

https://developers.facebook.com/docs/facebook-login/security/
On this page, there is a video that talks about security issues related to Facebook login. Around 13 minutes, he talks about oauth code flow. The idea is that if you're only making requests from the server, you should generate a code that you can then trade for an access token on the server.
To do this, you set response_type to code in the query params.
My question is how do you do that with the SDKs? The video suggests that you need to set Client Oath Login to false in the settings:
I did that, but I can see in the Chrome network tab that the SDK is still setting response_type to token. The result is this error:
What am I missing?
TL;DR I want to use the Facebook login dialog to get an access code that I can trade for an access token on the server.

Related

Facebook native login experience using Authorization Code flow (Redirected to the Facebook native App instead of the browser) - IdentityServer4

I am working on some OAuth 2.0 standards and non-standards flows to allow some clients to take the advantages of the SSO and give the users the native experience regarding the client that he/she working on.
One of the clients is a flutter App, so I followed the Authorization Code Flow with PKCE. The flow itself is a pretty straight forward to open a browser so you can exchange the code in this front channel with the access token through a backchannel. Things getting a bit complex while trying to authenticate via an external provider like Facebook. From the OAuth standard, it's easy to just pass the &acr_values=idp:Facebook.
The problem is when trying to follow the Authorization Code Flow with PKCE or even the old implicit flow to get access token through the Facebook, it opens the browser to ask you entering the Facebook username and password, but this is not the native experience as instead of that I want the web view to redirect the user to the app to authenticate via it instead of the browser like what's happening using the native Facebook SDK or Firebase SDK?
The only solution that I am following right now is following a non-standard authentication flow that I implemented myself to use the Flutter's Facebook SDK to get the Facebook token then exchange this token with my IdentityServer4 token after that (described here) which seems very user-friendly experience but complex and at the same time not standard.
So, is it a way to use the Authorization Code Flow with PKCE to get the access token from the IdentityServer4 using Facebook as an external provider and use the Facebook app instead of the browser to authenticate so we can give the user a native experience and follow the best OAuth2.0 practices at the same time??

OAuth2 : redirect_uri post LinkedIn & Facebook

I'm performing the server side oAuth2 flow.
I noticed that google has added a cool feature for their oAuth2 signin API which is redirect_uri=postmessage so we don't show the real redirect_uri on the browser url bar and the authorization code won't be included in the redirect url.
For linkedin, when the users accepts to share his personal data with the app, the response url looks like :
http://dev.localhost.com:8080/auth/linkedin?code=xxxxxxxxxxx&state=yyyyyyyyyyyyy
it's the same for Google unless we replace the real redirect_uri by postmessage.
If the redirect_uri + the response code is set in the url Every malicious script could be able to retrieve the returned code from the url and perform its own authentications.
So, is there any way to hide the return parameters and the redirect_uri for LinkedIn and Facebook ?
LinkedIn and Facebook are not vulnerable to malicious scripts accessing the redirect_uri.
Assuming you use the recommended response_type=code both APIs require you make a request from your server that includes your API secret and the code value in order to get the users token. LinkedIn describes this in Exchange Authorization Code for a Request Token and Facebook describes this in Exchanging code for an access token.
Additional security with Facebook can enabled with requiring that every request be signed with your API secret. Additional protection in general can be had by using a strong Content Security Policy to help prevent malicious scripts from running in the first place. And be sure to host your site exclusively over TLS to prevent your own JavaScript from being modified.

Facebook App Login - Exchanging code for an oauth access token is working only once

I'm using the URL below to get the auth token:
https://www.facebook.com/dialog/oauth?client_id=CLIENT_ID&redirect_uri=RETURN_URL&scope=manage_pages,publish_stream
This page will redirect to another URL with the code token in query string. I'm using this code token to get the Page access token automatically and publish to the Page 'offline'.
In recent days, it seems that Facebook has changed the expiration time of this token code.
I am able to use this token once. The time expiration is very short. Anyone know if there really was a change in facebook? Is there any other alternative to work with this?
This was part of the December 5th changes on the Roadmap: the code can only be exchanged for an access_token once and must be exchanged within 10 minutes of generation.
New security restrictions for OAuth authorization codes We will only
allow authorization codes to be exchanged for access tokens once and
will require that they be exchanged for an access token within 10
minutes of their creation. This is in line with the OAuth 2.0 Spec
which from the start has stated that "authorization codes MUST be
short lived and single use". For more information, check out our
Authentication documentation.
If you're unsure how to log users in correctly because you were relying on the old, incorrect behaviour, ensure you're using the newest SDKs and read the Login documentation in detail, specifically the Server Side Login documentation which shows how to exchange the code for a token
Once you have the token, save it using whatever session storage mechanism your app uses (PHP SDK will store it in a PHP session for you) and use the access token on subsequent calls instead of trying to obtain a new access_token from the code

Interaction with Facebook API without full OAuth, is it possible?

I need to post message on a certain FB page as a owner by cron, using php and ZF 1.1.X. For this small issue, I don't want to create a full OAuth stack. Is it possible to communicate with FB API (it's desirable, PHP SDK for FB) without it, such as twitter with his precreated access tokens (Access token, Access token secret)?
As long as you need an active user access_token to retrieve desired data this is not possible to skip OAuth flow.
Without authenticating user you only have application access_token (in old format APP_ID|APP_SECRET, but it's still works) and only limited access to most of Graph API endpoints and Application settings.
Actually there is nothing hard in implementing the user authentication with OAuth flow and it is completely transparent with usage of PHP-SDK.
Just look at the sample code in documentation for server-side authentication
Yes, you need to build an app and then authorize the page via the app while requesting the manage_page permission.
You should make yourself familiar with the Server Side Auth process as well.

Why can't I use server-side flow oauth tokens for an iOS app feed dialog?

I am working on a product which has both a desktop web site and a native iOS application. We are providing Facebook connect as a login option for our users in both contexts.
My intention was to share the same Facebook tokens via a secure JSON API for use in both contexts: when a user signs in on the web, the token is stored to our backend so that when the mobile client next runs, it can download the token and use it as well, and vice-versa. (* The detailed reasoning for this approach I explain at the end of the question, and is not essential to the question.)
The problem: when the iOS client uses a token to preset a feed dialog, if that token is generated by the web using the server-side flow, the dialog webview renders an error:
"An error occured with {my app name}. Please try again later."
This is reliably reproducible:
Generate a new access token using the server-side flow. Make sure you request publish_actions permission since you'll be using the feed dialog.
Using an incognito browser window (to get an empty cookie jar), view the m.facebook.com page that the iOS feed dialog would render in its webview: https://m.facebook.com/dialog/feed?access_token=SERVER_SIDE_FLOW_ACCESS_TOKEN&app_id=YOUR_APP_ID&redirect_uri=fbconnect%3A%2F%2Fsuccess&sdk=2&display=touch
Alternatively to #2 you could do all the work (which I have done already) of creating a dummy iOS app with the Facebook SDK, instantiating it correctly and presenting the dialog. It's just easier to go straight to the m.facebook.com feed URL for the purposes of reproducing the error.
If the token was generated by the auth flow initiated by the native Facebook iOS SDK instead of the server-side auth flow, the above feed url works perfectly fine, as expected.
Additionally, either token (mobile or server generated) works perfectly fine for posting feed items directly via the graph api. The problem is really just with the mobile feed dialog.
Is Facebook intentionally disallowing server-side generated tokens from operating in mobile feed dialog contexts?
Is this a bug with the feed dialog endpoint on m.facebook.com?
Or, hopefully, am I doing something wrong?
Why do I want to share tokens?
Since the offline_access permission is being removed, each client (web vs mobile) can benefit from having the other client refresh the same token when the user is active. This will lead to fewer instances of token expiry, and therefore fewer cases in which users must re-authenticate from scratch.
Likewise, users are not asked so frequently to approve additional permissions, since each client can benefit from the other's permission augmentations.
The tokens you get from the server side auth are different from the ones on the client side (I look at iOS/Android as client).
The server tokens are long lived one (60 days) while the client ones are short lived (a few hours).
The server side flow adds another layer of security where your servers authenticate against the facebook servers, which is probably why you get a long lived token automatically when using this flow.
If you try the debugger with an access token you will receive information about the token, such as the "origin" of the token.
For example a token generated from a client side auth (using js) has "Origin: Web".
That means that facebook indeed differentiate between tokens.
I'm not 100% sure about this, but from what you're saying it does sound like facebook is limiting the UI to the usage of client tokens and not server side ones, probably because the dialogs let the user do things without the need of the app to get permissions, and so if you have a 60 days token your app can then use it instead of the user and do things on his behalf with out having his permission.
I'm just guessing here.
What I would recommend you is to use the server token only on the server side, and let the iOS client handle his own token.
According to the Handling Invalid and Expired Access Tokens guide, it states:
iOS native applications
API errors are handled by the FBRequestDelegate interface. When you
detect an access token is invalid or has expired, your application
will need to multi-task over to the Facebook iOS app. Assuming the
user has not deauthorized your app, they will be immediately
multi-tasked back to your iOS application with a fresh, valid access
token.
Which means that you don't have to worry about the token getting expired on the client side.