Facebook Oauth Servicestack not working - single-sign-on

We have been using servicestack as framework for web services, we also uses its SSO with FB, LinkedIn, GooglePlus features.
We enable them like this
Plugins.Add(new AuthFeature(() => new AuthUserSession(),
new IAuthProvider[] {
new FacebookAuthProvider(appSettings),
new GoogleOAuth2Provider(appSettings),
new TwitterAuthProvider(appSettings),
new LinkedInOAuth2Provider(appSettings)}
From 3/27 the FB SSO stops working on our site but the other SSO's like LinkedIn works fine. When I debug for facebook SSO, we are getting the Auth_Code from the FB back to our services, but I am assuming the server to server communication is failing while passing(code, secret). It is just an assumption made as the Auth_token is not set in session. If you came to know that FB updates something in OAuth process that ServiceStack not follows or anything like that, please provide me that info links.
I am wrong in my assumption "we are getting the Auth_Code from the FB back to our services, but I am assuming the server to server communication is failing while passing(code, secret). It is just an assumption made as the Auth_token is not set in session." Using the fiddler I am able to see the server-to-server communication for exchanging Auth_Code, Client_Secret with Access_Token. I see the Token response. After that I was taken back to my ReferralURL. In my Referral end point I am getting the Usersession.ProviderOAuthAccess, It has the Facebook provider but I don't see any Token information in it. This is really an interesting chase. Please help me with any other ideas to test.
I found added info: After getting the Access_Token froom FB, the immediate call is https://avatars.io/facebook/?size=medium initiated by service-stack.
https://github.com/ServiceStack/ServiceStack/blob/v4.0.50/src/ServiceStack/Auth/FacebookAuthProvider.cs
At line 73 of FacebookAuthProvider.cs it calls OnAuthenticated function whoch calls OnAuthenticated function at line 171
https://github.com/ServiceStack/ServiceStack/blob/v4.0.50/src/ServiceStack/Auth/CredentialsAuthProvider.cs
which calls the function SafeAddMetadata at line 177 of the file
https://github.com/ServiceStack/ServiceStack/blob/v4.0.50/src/ServiceStack/Auth/AuthMetadataProvider.cs
Finally triggers this:
"http://avatars.io/facebook/{0}?size=medium".Fmt(tokens.UserName));
Which seems that the tokens.username is empty from my network flow. This issue is beyond my thinking. It used to work, just stopped suddenly not sure what happened, we even don't even upgrade servicestack or servicestack.OAuth packages.

Related

How to call Salesforce REST API from external web forms

I am a bit confused. The requirement is that we need to create a REST API in Salesforce(Apex class) that has one POST method. Right now, I have been testing it with POSTMAN tool in 2 steps:
Making a POST request first with username, password, client_id, client_secret(that are coming from connected app in Salesforce), grant_type to receive access token.
Then I make another POST request in POSTMAN to create a lead in Salesforce, using the access token I received before and the body.
However, the REST API that I have in Salesforce would be called from various different web forms. So once someone fills out the webform, on the backend it would call this REST API in Salesforce and submits lead request.
I am wondering how would that happen since we can't use POSTMAN for that.
Thanks
These "various different web forms" would have to send requests to Salesforce just like Postman does. You'd need two POST calls (one for login, one to call the service you've created). It'll be bit out of your control, you provided the SF code and proven it works, now it's for these website developers to pick it up.
What's exactly your question? There are tons of libraries to connect to SF from Java, Python, .NET, PHP... Or they could hand-craft these HTTP messages, just Google for "PHP HTTP POST" or something...
https://developer.salesforce.com/index.php?title=Getting_Started_with_the_Force.com_Toolkit_for_PHP&oldid=51397
https://github.com/developerforce/Force.com-Toolkit-for-NET
https://pypi.org/project/simple-salesforce/ / https://pypi.org/project/salesforce-python/
Depending how much time they'll have they can:
cache the session id (so they don't call login every time), try to reuse it, call login again only if session id is blank / got "session expired or invalid" error back
try to batch it somehow (do they need to save these Leads to SF asap or in say hourly intervals is OK? How did YOU write the service, accepts 1 lead or list of records?
be smart about storing the credentials to SF (some secure way, not hardcoded). Ideally in a way that it's easy to use the integration against sandbox or production changing just 1 config file or environment variables or something like that

Play Framework authentication: request headers are not being added in production

I have implemented an authorized action as explained in this question as well as the answer by #vdebergue.
This was working great, and the requests made by the front-end application were automatically adding an X-XSRF-TOKEN request header, with the token obtained from the login response.
However upon deploying both front-end and back-end, the requests issued from the browser are no longer adding the X-XSRF-TOKEN request header, thus causing an Unauthorized response from the server (rightfully so).
What I am failing to understand is, what is it that changed between development and deployment?
I do have the request header specified in cors.allowedHttpHeaders:
play.filters.cors.allowedHttpHeaders = ["Accept", "Origin", "Content-Type", "X-XSRF-TOKEN"]
I doubt I have to add this header manually from React (in fact the issue probably has nothing to do with the front-end).
Thanks!
Edit 1:
List of XHR requests:
Details of the login POST request, can see the X-XSRF cookie and the token being passed:
Details of the unauthorized GET that is not setting the X-XSRF as request header:
Same as previous screenshot, but running on localhost, getting authorized with the header added:
Assuming you implemented correctly, and the cookie is not attached during deployment, the issue might be related to the domain of your cookie. The way I did it is to define an an env variable and use it to hold the domain value; so it does not break the implementation during development and tests.
You can look at the Playframework API documentation for more information on how to use the cookie.
Solved in an unconventional matter: front end was made with react, which offers a way to build a static production version.
I simply integrated those static files with play framework's index.scala.html, instead of trying to run it as a separate app on a different port.
It works, however i will not mark it as a best answer yet, because i don't know whether a mobile app connecting to the same play framework backend will play along nicely when it comes to authorisation and cookies. Mobile apps are not browsers (and maybe don't abide by their limitations), and Postman had no issues with cookies.
To be checked.

Error response client_not_active when trying to obtain access token using curl

I'm going step-by-step Nest REST Quick Guide and now blocked with error response during attempts to obtain an access token.
Response is:
{"error":"client_not_active","error_description":"client is not active","instance_id":"here_is_something_looks_like_guid"}
I've checked Error Messages Guide, and it helps me a lot to understand that "Client not active". Useful, huh?
So which client and how to activate it?
I have a home simulator working, also I've registered a so-called 'product', which I want to develop (so I have Product ID, Product Secret, Authorization URL and Access Token URL).
[Upd]
For all operations I've used curl.
However with Firefox addon which sends POST data I'm able to obtain the access_token. So I keep the question, but so far will stick to browser.
This means the your product/client has been deactivated, most likely due to a violation of the Terms of Service. Is the problem consistently occurring?

Architecture for User-Registration (here: With using Facebook)

Im writing a user registration mechanism by hand so I dont want to use existing plugins or something.
Im wondering what the best way would be. I planning to do the following abstract steps:
Writing an component which is in charge to output a button which calls the facebook-api --> login in via facebook (Im getting token and user name/id)
In my route im using that Data to call the REST-Server-Backend of my app. I will pass the token as well as the username/id to the Server. (POST api.myapp.com/users)
The Server recieves the request and will validate via Facebook-API
the user data and token on its own --> if valid: Add new user to
database.
If the user wants to login now (after registration) he will do again
step no.1 and than will ask the server if the user is existing. But
how: Since ember suggest that the REST-Server is somekind of a
CRUD-Server and using the store is for working for model data only, there
is no possiblity to do a "logic"-call to the server like "ask
him if user with id is existing". Should I call "GET ../users/" and than check in my route if the sum of the returned records are smaller than 1?
So is that a common pattern?
Sounds like a fairly simple OAuth workflow but obviously refer to the facebook docs. As far as point 4 is concerned, I would suggest that yes, on login you make a request for the login route on your server (which should abstract the facebook OAuth call), and if the user is authenticated, then send down the user resource, otherwise redirect them to the login and send down some sort of 401 HTTP error.
As all your API calls should be authenticated too your user won't be able to access any protected API resources.
I would also suggest you look into an ember plugin like ember-simple-auth which also supports OAuth.
You can find more information about OAuth2 workflows here.

How to pass Facebook Id from client to server securely

I have a Facebook canvas app. I am using the JS SDK to authenticate the user on the browser-side and request various information via FB.api (e.g. name, friends, etc.).
I also want to persist some additional user information (not held on Facebook) to the database on my server by making an ajax call:
{ userFavouriteColour: "Red" }
To save this on the server and associate with the correct user, I need to know the Facebook uid and this presents a problem. How do I pass the uid from the client to the server.
Option 1: Add uid to the ajax request:
{ uid: "1234567890",
userFavouriteColour: "Red" }
This is obviously no good. It would be trivial for anyone to make an ajax request to my web service using someone else's Facebook Id and change their favourite colour.
Option 2: On the server, extract the uid from a cookie:
Is this even possible? I have read that Facebook sets a cookie containing the uid and access token but do I have access to this cookie on my domain? More importantly, can I securely extract the uid form the cookie or is this open to spoofing just like option 1.
Option 3: User server-side authentication on the server:
I could use the server-side authentication to validate the user identity on my server. But will this work if I am already using client-side authentication on the browser? Will I end up with two different access tokens? I would like to make FB.api requests from the browser so I need the access token on the client (not just on the server).
This must be a very common scenario so I think I'm missing something fundamental. I have read a lot of the Facebook documentation (various authentication flows, access tokens, signed_request, etc.) and many posts on SO, but I still don't understand how client-side authentication and server-side authentication play nicely together.
In short, I want to know the user's identity on the server but still make requests to the Facebook api from the client browser?
(I am using ASP.NET and the Facebook C# SDK on the server)
EDIT: Added bounty. I was hoping to get a more deifnitive, official recommendation on how to handle this situation, or even an example. As said, I have already read a lot of the official FB docs on authentication flows but I still can't find anything definitive on how client-side and server-side authentication work together.
Option 1:
The easiest way I can think of is to include the accessToken in JS and pass it with the ajax call.
Option 2:
Using the same as option 1, but instead of sending just the accessToken, send the signedRequest.
On the server side you can decode it using (TryParseSignedRequest method) which will give you the UserID :-)
Note: signedRequest is encrypted with the application Secret. you are the only one who should know it, so you are safe on that end.
Disclaimer:
I have no coding experience in C#, but a little search in google gave me this:
Facebook C# SDK for ASP.NET
Making AJAX Requests with the Facebook C# SDK
It's very simple actually.
When the user loads you app use the server side authentication, get the access token and load the user data by issuing an api request from the server.
On the server side you'll have everything you need and it's sandboxed.
When the page renders for the user, using the js sdk get the user authentication data, you should be able to use FB.getLoginStatus since the user already went through the server side authentication.
Now on the client side you also have an access token which you can use to get the user data from the graph api.
The two tokens will be different, and will also have different expiration, but that should not be a problem, both token should work properly as you'd expect them to.
Since both sides have their own token and a way to make requests to the api, there's no need to send any fb data between them.
So the 3rd option you mentioned, to me, sounds the best, and it's really simple to implement that too.
Edit
All facebook SDKs are just wrappers for http request since the entire fb api is made on http requests.
The SDKs just give you easy and shorter access to the data with out the need to build the url yourself (with all the different possible parameters), make the request and parse the response.
To be completely honest, I think that stop providing a way for the C# SDK to support server side authentication is a very bad decision.
What's the point in providing a SDK which does not implement the entire api?
The best answer to your question, from my experience, is to use both server and client side authentication, and since the C# SDK does not support it, my advice to you is to create your own SDK.
It's not complicated at all, I already implemented it for python and java (twice), and since you'll be developing it for your own needs it can be tailored for your exact needs, unlike a public SDK which should support all possible options.
2nd Edit
There's no need to create a completely new SDK, you can just "extend" the ones you're using and add the missing parts that you need, like sever side authentication support.
I don't know if it's language specific but using both server-side and client-side authentication does no harm.
You can work on option 2 but yes, that will be also vulnerable to spoofing.
Doing option 3, you will be having a single access token for that user session, so that would be the best choice according to me since you always have chance of spoofing when passing user information from client side.
I had exactly the same question recently. It's option 2. Check this post from the Facebook blog.
To be honest I am not enough of a hacker to know if you could spoof the UID in the cookie, but this seems to be the 'official' way to do it.
EDIT: to the other question under option 2, yes, I believe you have to access this cookie on your domain.