Facebook Graph API Requests from .NET (C#) - c#

I have an application that generates a web request to Facebook Graph API to get a share count from an external page. I have been using this code for over a year without issue, and suddenly, the share count is not working when the request is made from .NET. However, if I make the request from a web browser, it works just fine. My code is as follows:
string fbLink = "https://graph.facebook.com/?id=" + externalLink + "&fields=og_object%7Bengagement%7D&access_token=<token_removed>";
WebClient client = new WebClient();
string fbString = client.DownloadString(fbLink);
This code still appears to be working fine, in that the request is made, and FB responds with no errors. In fact, it responds back with correct page id, and details. However, the share count is zero.
Here is where it gets a little bit weird. On my localhost development machine, the code works fine and returns the proper share count. However, if I run the code on my actual server (an AWS EC2 instance), the share count shows zero.
If I open Chrome and run the request from the browser, the share count displays as expected.
If I open Internet Explorer 11, and run the request from the browser, the counter shows zero. HOWEVER, if I log in to Facebook from IE11, and then run the request to FB Graph API, the response shows the correct page count.
This is very confusing to me, as it appears the reason the counter has stopped working, has to do with cookies, or maybe the browser being logged into FB. This should not be the case as I am using an APP token ID, and I wouldn't expect to need to be logged into FB in order to make a request to Graph API.
Does anybody have any ideas why my request/code in .NET worked just fine for a year and a half, and just stopped working? Or why the requests work fine on my localhost and not my live server?

After spending considerable time on this issue, I have fixed the issue. There is a FB authentication cookie that was being transmitted through a web browser query. The cookie name was "XS" and the value was a long string that is used as a sessionId for my specific login. If I created this cookie in my web request in C# code, I get the proper response with correct # of shares.
WebClient client = new WebClient();
client.Headers.Add("Cookie", "xs=<removed>;");
I have no idea why I have to do this, only on my EC2 server. Nowhere in FB's documentation does it say you have to spoof a valid logged in authentication string cookie in order to obtain correct Share Count results from a request to it's Graph API, but there you have it. A workaround at least.

Related

ASP NET Web API google authentication issue HTTP 404

I am trying to setup a social login for my site.
Here is what I did:
I created credentials on google and have both ClientID and Secret
In default MVC app, in App_Start Startup.Auth.cs I uncommented
app.UseGoogleAuthentication()* method, so it looks like this:
Build solution!
Made sure authorized JavaScript origins and Redirect url are correct. And other things that are needed on console.cloud.google.com are done. Including activation of Google+ API
Eventually Google authentication button should appear in _ExternalLoginsListPartial partial view. But as I can see I have 0 login providers still. And not sure why, and what can I do about it?
var loginProviders = Context.GetOwinContext().Authentication.GetExternalAuthenticationTypes();
//loginProviders.Count() here returns 0
Tried researching, but most are saying that you forgot to build, or restart the server. Tried that but nothing changed.
As last resort, I tried following a tutorial https://youtu.be/WsRyvWvo4EI?t=9m47s
I did everything as shown there, I should be able to reach api/Account/ExternalLogins?returnUrl=%2F&generateState=true url, and receive callback URL from Google.
But I got stuck with same HTTP404 error at 9:50
To answer my question, everything turns out to be fine.
All I had to do was just to give it some time.
After couple of hours, Google provider appeared on the page.
For future readers - if met with 404 in this case, another possibility is an active filtering rule against query strings in IIS. One of the commonly copy-pasted rules aiming to block SQL injection requests scans the query string for open (to catch OPEN cursor). Your OAuth request probably contains this word in the scopes section (data you want to pull from the Google profile)
IIS -> Request Filtering
Switch to the tab "Rules"
Inspect and remove any suspicious active filters there

Request.Url.GetLeftPart(UriPartial.Authority) returns http on https site

We use Request.Url.GetLeftPart(UriPartial.Authority) to get the domain part of the site. This served our requirement on http.
We recently change site to https (about 3 days ago) but this still returns with http://..
Urls were all changed to https and show in browser address bar.
Any idea why this happens?
The following example works fine and returns a string with "https":
var uri = new Uri("https://www.google.com/?q=102njgn24gk24ng2k");
var authority = uri.GetLeftPart(UriPartial.Authority);
// authority => "https://www.google.com"
You either have an issue with the HttpContext class right here, or all your requests are still using http:
You can check the requests HttpContext.Current.Request.IsSecureConnection property. If it is true, and the GetLeftPart method still returns http for you, I think you won't get around a replacing here.
If all your requests are really coming with http, you might enforce a secure connection in IIS.
You should also inspect the incoming URL and log it somewhere for debugging purposes.
This can also happen when dealing with a load balancer. In one situation I worked on, any https requests were converted into http by the load balancer. It still says https in the browser address bar, but internally it's a http request, so the server-side call you are making to GetLeftPart() returns http.
If your request is coming from ARR with SSL Offloading,
Request.Url.GetLeftPart(UriPartial.Authority) just get http

Keep getting Error: redirect_uri_mismatch using youtube api v3

Hi I hope someone can help me out here.
I have a Web Application (asp.net) on my local machine, I am trying to upload video to YouTube using this sample https://developers.google.com/youtube/v3/code_samples/dotnet#upload_a_video
I have set up client id and secret for Web application in Google console when I try to upload video a browser tab opens to select one of my google accounts and once I sig in I get redirect_uri_mismatch the response details on that page are below:
cookie_policy_enforce=false
scope=https://www.googleapis.com/auth/youtube.upload
response_type=code
access_type=offline
redirect_uri=http://localhost:55556/authorize/
pageId=[some page id removed here for security reasons]
display=page
client_id=[some unique id removed here for security reasons].apps.googleusercontent.com
one interesting thing is that the redirect_uri=http://localhost:55556/authorize/ is completely different from the one set up in Google console and the one in client_secrets.json also each time I get the error page the port number changes.
redurect urls and origins are set as follows in Google console I think I have added all combinations just in case:
Authorized redirect URI
http://localhost/
https://localhost/
http://localhost:50169/AddContent.aspx
https://localhost:50169/AddContent.aspx
http://localhost:50169
Authorized JavaScript origins
http://localhost/
https://localhost/
http://localhost:50169/
https://localhost:50169/
I am not sure why redirect-uri on the error page does not match any of the
Authorized redirect URI I have specified in Google console ? any ideas ?
Also is it possible that everything is set-up correctly in Google console and my code but this error is triggered by something else like maybe I missed some setting on my you tube account ? I did not make any setting changes since I don't think I have to is that correct ?
Ok I belive that direct video upload to the website owner account is no longer supported in YT API v3.0 according to those posts.
Can YouTube Direct Upload to a Common Account for All Users?
How can I get the youtube webcam widget to upload to one account using API?
Shame, I think I will need to host the videos that users upload on my servers.
However the original issue was fixed by adding this URI to the redirect URIs in the developer console
http://localhost/authorize/
Google OAuth 2 authorization - Error: redirect_uri_mismatch
I got it to work by setting the Redirect URIs to exactly this:
http://localhost:50517/signin-google
Note:
- it does not work with a trailing slash
- port number is whatever your visual studio is assigning
- I set JavaScript Origins to:
http://localhost:50517/
With you, though, would be nice if someone actually documented this somewhere...
You should look into your code where you create the authorization URI. You need pass one of the redirect URIs you registered with Google developer console. I guess you're using some OAuth2 library which uses the localhost:port/authorize as the default redirect URI. The port changes because each time you start your local server, it picks a different port number. To fix it, you should specify a port number when starting it, for example, 8080. Then you should register localhost:8080/AddContent.aspx in Google developer console and pass it to whichever library you use to create the authorization URI.
I experienced a similar problem when trying to setup the quickstart app for the Drive REST API. I kept getting the redirect_uri_mismatch error and the port number with that error kept changing. The fix for me was to change the redirect URI in the Google Developers Console for my app to not include the port number.
There is a really easy way to get round this and I kicked myself when it dawned on me.
I am using "Web Application" credentials - you'll want the credentials manager open btw.
Run the DotNet sample app and let the browser open (I get the "Select An Account" page) - then look in the URL for the redirect URI that's been automatically generated by Google's code something like:
redirect_uri%3Dhttp://localhost:62041/authorize/
Then just go to the credentials manager and add this URL to the allowed list and save. Now select your google account and see what happens - it takes a few minutes for the API to update - if you get the redirect error page just hit back and select you account again - eventually it works and returns back to visual studio.
Once the account has been authorised once it sticks (clear the bin directory to unstick it) but this means you can now put a break point in the code and look at the credentials variable to get the refresh token everyone is so desperately trying to get so that you can persist account connections.

Two OpenID Authentication Responses Returning from Yahoo using Internet Explorer

I'm working on an application allowing users to sign in and register using Google and Yahoo through OpenID using ASP.NET MVC4, and the DotNetOpenAuth library. Google is working fine, and Yahoo was working fine for a few months as well until a few days ago.
For some reason, using my local version of IE 11, after authenticating with Yahoo, two responses are sent back to the web server, and each is validated in its own separate thread. One response is determined to be valid, and the other response is determined to be invalid because the first response is already validated. The responses are then sent back to the user, and depending on which one is sent first, two very different outcomes can occur.
Using Chrome and Firefox works correctly. Yahoo is returning only one response. Using different versions of IE on other machines (including 11) work correctly as well. Using fiddler, I've verified that the correct requests are being sent out. I've tried clearing my cache, disabling any addons, and changing document and browser modes using the dev tools, and no luck. Is there anything that can be causing two responses to be sent back?
The basic code to send the request is below. The config file is using all default values.
OpenIdRelyingParty openid = new OpenIdRelyingParty();
IAuthenticationRequest request = openid.CreateRequest(Identifier.Parse("https://me.yahoo.com"));
var fields = new ClaimsRequest();
fields.Email = DemandLevel.Require;
request.AddExtension(fields);
return request.RedirectingResponse.AsActionResult();
It turns out that the problem was that I was sending a request to tell Yahoo to redirect back to an unencrypted connection after authentication. If I tell Yahoo to return to an https url, rather than http, everything works correctly, and I only get one request coming back to the application.

401 when POSTing using HttpWebRequest (yes I used Credentials)

I'm using HttpWebRequest to pull down XML, and POST data back to a 'WebService' and getting a 401 on the POST.
When creating the requests I've added Credentials and now tried a credentials cache and setting PreAutenticate to True, still getting the 401! :(
Watching the HTTP traffic on the router I set the get make an unauthenticated GET request.. it hits the 401 and then makes an authenticated GET and is allowed through. When I watch the POST I see it hit the 401... and it doesn't even try an authenticated POST.
This appears only on mobile phones (compact-framework 3.5 and 2.0 on WinMobile 6.1). The same .exe works perfectly on any desktop machines.
What am I missing? Please help!
Try setting the header manually:
http://devproj20.blogspot.com/2008/02/assigning-basic-authorization-http.html

Categories