Facebook Graph API Explorer behind HTTP Basic Auth - facebook-opengraph

I keep getting the following error when I try to test one of my pages with Graph API Explorer:
{
"error": {
"message": "(#3502) Object at URL https://example.com/place/123456-Something has og:type of 'website'. The property 'bar' requires an object of og:type 'example:bar'. (http response code: 401)",
"type": "OAuthException",
"code": 3502
}
}
The problem is that this page is behind HTTP Basic Authentication and it returns 401 Unauthorized even if I pass proper credentials to authenticate for this page. I can't believe it but this seems to me that Graph API Explorer does not support HTTP Basic Authentication. Does anyone had this issue before and know how to force Graph API Explorer to be able to authenticate?

If the scraper (https://developers.facebook.com/tools/debug) cannot reach your page then it's not possible.
Open Graph pages must be public and reachable.
Using self-hosted objects requires that you host them as pages on your own webserver and all self-hosted objects are public.
https://developers.facebook.com/docs/opengraph/using-objects/

You can either punch a hole in basic auth via user agent (not secure, since that is trival to spoof) or Facebook's published list of crawler IP addresses.
I've written a quick PHP script here to generate an htaccess that includes simple auth and those IPs. FB says they shift the crawler IPs, so you'd want to do cron that script to regenerate the htaccess every so often.

Related

Automatic sign-in not working on server URL (localhost works)

I'm trying to sign in automatically when possible using following code (TypeScript, called from a React app):
google.accounts.id.initialize({
client_id: envSettings.auth.google.clientId,
callback: signInWithJwt,
auto_select: true,
});
google.accounts.id.renderButton(domElement, {
theme: "outline",
});
google.accounts.id.prompt();
I now have following situation:
Signing in via the rendered button always works (locally and on my "Static Web App" hosted in Azure)
google.accounts.id.prompt() however only works on localhost but not on the server, even though the URLs are added in the "Authorized JavaScript origins" section in the Google console. I get following message in the browser console: [GSI_LOGGER]: The given origin is not allowed for the given client ID.
The only difference I see between localhost and the server is that server is running on https and localhost is using http.
For me this does not really make sense, as obviously it does work with the button. Any thoughts on what is wrong here?
You need to follow the message, "The given origin is not allowed for the given client ID." Go to the google cloud console, and allow the origin that your server is on. Go to your project > APIs and Services > Credentials > your OAuth 2.0 Client ID, and edit it to allow your domain to be authorized.
This is for security purposes, so that a malicious actor cannot use your client ID to pose as your app on another domain, and access your users' data.
Google documentation
Found the issue thanks to this post: https://stackoverflow.com/a/70739451/4092115
I had to set the referrer policy in my index.html as follows:
<meta name="referrer" content="strict-origin-when-cross-origin" />
https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Referrer-Policy

WooCommerce - Auto generating API keys using our Application Authentication Endpoint give 401 Invalid URL error

I'm attempting to use the REST API provided by WooCommerce to generate the Customer Secret and Customer Key values so that it could be used to invoke other WooCommerce REST APIs. I referred the documentation about generating the key values and managed to get it working using a mock endpoint in Postman used for the call_back URL in the API as mentioned in the document.
I created a POST service in my backend server and managed to setup a SSL certificate in the local environment with a domain mapped in hosts file in /etc directory. I ran the backend service and invoked the callback url through Postman and it worked. Then I used that as the call_back URL in the actual WooCommerce Auth endpoint to programatically generate the keys and save it in my DB. But I'm getting
"Access Denied" - Error: A valid URL was not provided..
When I checked the browser through devtools -> network noticed that there is a 401 Unauthorize error.
Here is the sample GET URL that is uesd for WooCommerce API key generation
http://localhost/woocommerce/wc-auth/v1/authorize?app_name=<SOME_NAME>&scope=read_write&user_id=36&return_url=http://localhost/woocommerce/&callback_url=https://foo.bar.dev:44329/api/services/app/woo_commerce_auth/6/callback
callback_url = https://foo.bar.dev:44329/api/services/app/woo_commerce_auth/6/callback
When the callback_url is a mock url generated using Postman it works fine
callback_url = https://513ca6ab-db16-4635-8d0b-9159e3b1e187.mock.pstmn.io/api/services/app/woo_commerce_auth/6/callback
Any clue why this happens, I could not find a way to troubleshoot this issue. Appreciate the help.
Hi posting this for future reference, and hope it would help others who face this problem as well.
Things to keep in mind when setting the callback_url,
Non HTTPS URL endpoint are not allowed.
URL should not be a localhost url (e.g localhost/callback would give an invalid URL error)
URL should not contain port number (e.g localhost:4320/callback or foo.bar.dev:4892/callback are invalid)
Callback URL should be a POST url
If an error such as Error: An error occurred in the request and at the time were unable to send the consumer data. is given after checking all the above check the backend service code related to the callback_url (I had a 500 server error which triggered this, it was not a WooCommerce issue)
Also a tool such as ngrok would be really helpful to setup an HTTPS endpoint in your local environment to test this.

Microsoft application - Redirect URI allows 'localhost' but not '127.0.0.1'

I have developed an application that allows MSA (Microsoft Account) authentication. I have registered my app here: https://apps.dev.microsoft.com.
When testing my app locally, I can access my app with no problem at my SSL URL of https://localhost:44300, and MSA works fine. When I registered my app, I used https://localhost:44300/signin-microsoft as the Redirect URI.
Problem: I can also access my app at https://127.0.0.1:44300, as one would expect. However, MSA here doesn't work. The error page says, We're unable to complete your request.
Microsoft account is experiencing technical problems. Please try again later. And the URL of the error page reveals that the error is with a mismatch in the Redirect URI: https://login.live.com/err.srf?lc=1033#error=invalid_request&error_description=The+provided+value+for+the+input+parameter+'redirect_uri'+is+not+valid.+The+expected+value+is+'https://login.live.com/oauth20_desktop.srf'+or+a+URL+which+matches+the+redirect+URI+registered+for+this+client+application.
In the Microsoft Apps page, when I try to update the Redirect URI from https://localhost:44300/signin-microsoft to https://127.0.0.1:44300/signin-microsoft, it doesn't allow me to save my change and it shows me this error: Your URL can't contain a query string or invalid special characters, and it provides a 'Learn More' link: https://learn.microsoft.com/en-us/azure/active-directory/active-directory-v2-limitations#restrictions-on-redirect-uris
After reading the info in this link, I see nowhere that a URI like mine (https://127.0.0.1:44300/signin-microsoft) would be an unacceptable URL, as I'm not breaking any of their rules: I have no invalid characters, no query strings, etc.
My research: Looking online, people are getting the Your URL can't contain a query string or invalid special characters because they are actually using a query string or invalid special characters, such as in this link: https://social.msdn.microsoft.com/Forums/en-US/4f638860-ea57-4f0e-85e0-b28e1e357fe2/office-365-app-authorization-redirect-uri-issue?forum=WindowsAzureAD. I couldn't find a case where someone has entered a valid URI and they weren't allowed to save it.
Why I need 127.0.0.1 to work: I need to expose this website, which is running on my local box. In order to have the website running without having an instance of Visual Studio opened all the time, I'm using csrun to host my website in Azure local fabric (by the way, my app is an Azure Cloud Service, with a ASP.NET MVC 5 app as a web role). I followed this instruction for csrun: http://www.bardev.com/2013/03/12/how-to-deploy-application-to-windows-azure-compute-emulator-with-csrun/. Using csrun, it allowed me to host my website in https://127.0.0.1:444 (but, as with https://127.0.0.1:44300, MSA doesn't work). My end goal is to expose this website with a public URL using ngrok (https://www.sitepoint.com/use-ngrok-test-local-site/), so that anyone can access my site.
Therefore, my main question is: how can I have the Redirect URI be https://127.0.0.1:44300/signin-microsoft instead of https://localhost:44300/signin-microsoft?
Make sure you access this portal through https://identity.microsoft.com as this is the only way the steps below will work.
You can get around this error right now by adding the reply URL through the manifest. Login to the portal, select the app you want to configure, and scroll down and hit the Edit Application Manifest button. Then you can add your https://127.0.0.1:44300/ to the replyUrls field.
There's some funny behavior that will only allow this right now if you only register other localhost reply Urls. If this is the only reply URL you need then it shouldn't be a problem.

Setting webhook results in 'Unauthorized WebHook callback channel' . Everything should be fine

Time to go to SE, since this has cost me more then 4 hours now.
I'm trying to setup a webhook (https://app.example.com/notications) for Push Notifications coming from Google Drive API.
After having set-up everything I'm getting error:
...
errors": [
{
"domain": "global",
"reason": "push.webhookUrlUnauthorized",
"message": "Unauthorized WebHook callback channel: https://app.example.com"
}
],
...
There are a couple of results on google (most of which are here on SE) that talk about this issue. None of the solutions presented seem to work for me. Needless to say, I would be pretty much tearing my hair out if I had some.
This I what I've tried:
As explained here there are some requirements:
Step 1: Verify that you own the domain. (Complete the site verification process using Webmaster Tools)
Registered app.example.com, through Webmaster Tools. Separately also verified example.com although this should not matter. Check!
Step 2: Register your domain:
Go to the Google Developers Console.
Choose or create a project.
In the sidebar on the left, click APIs & auth, then click Push.
Click Add domains.
Fill in the form, then again click Add domains.
Done for app.example.com. Check!
Note that the Drive API will be able to send notifications to this HTTPS address only if there is a valid SSL certificate installed on your web server. Invalid certificates include:
Self-signed certificates.
Certificates signed by an untrusted source.
Certificates that have been revoked.
Certificates that have a subject that doesn't match the target hostname.
What I've done:
I've setup app.example.com with an SSL certificate.
Moreover the endpoint is reachable and everything checks out.
SSL checker has verified that everything is okay (5 ticks). Even the SSL-chain is setup correctly. Check!
constructing a POST query
to the simple https://www.googleapis.com/drive/v2/changes/watch endpoint
containing a Authorization: Bearer x header
containing a Content-Type:application/json header
Post contains a body as follows
{
"id": "someIdThatDoesntMatter",
"type":"web_hook",
"address": "https://app.example.com/notifications"
}
Check!
I'm running all this through Postman (a Chrome extensions to test http requests) so there's no app at my side that can be interfering.
What on earth could be the problem?
It was very weird but somehow it works.
When adding domain use complete URL with https://app.example.com/notifications
try the complete URL with a trailing slash when making calendar API call
{
"id": "someIdThatDoesntMatter",
"type":"web_hook",
"address": "https://app.example.com/notifications/"
}
Step 4's POST body address: "https://app.captured.io/notifications" should be "https://app.example.com/notications". Or the other way around. Either way, they should all match so we can understand whether that's merely a typo in your post or truly the answer to your question. :)
Oh; and in "https://app.example.com/notications", "notications" is misspelled. It should be: "https://app.example.com/notifications". ... Or the other way around if that's your thing :)
It's also worth noting, per their documentation:
A watch request will not be successful unless the current user or service account owns or has permission to access this resource.

GAE Federated Identity Login HTTP 204

I've searched the site but can't find anything that exactly matches this situation.
Cliff's Notes:
Trying to implement Federated login on GAE, using the sample python code at https://developers.google.com/appengine/docs/python/users/, with a custom OpenID Provider. GAE returns either at HTTP 500 or HTTP 204 depending on the server setup. There are no entries in the application logs on the admin console. Most likely it is a problem to do with the XRDS file and the discovery process. I'd appreciate any suggestions as to a cause or possible debugging methods. Thanks in advance.
Problem Details:
The code works fine when using the following providers in the 'federated_identity' parameter of the users.create_login_url() function:
https://www.google.com/accounts/o8/id
yahoo.com
aol.com
myopenid.com
The issues start when trying to use our own custom OpenID Provider. We have set up the OpenID plugin on a couple of Wordpress installs on different hosts for testing purposes. The plugin makes use of XRDS-Simple to publish the XRDS document at domain.com/?xrds. Example document contents:
<?xml version="1.0" encoding="UTF-8" ?>
<xrds:XRDS xmlns:xrds="xri://$xrds" xmlns="xri://$xrd*($v*2.0)" xmlns:simple="http://xrds-simple.net/core/1.0" xmlns:openid="http://openid.net/xmlns/1.0">
<XRD xml:id="main" version="2.0">
<Type>xri://$xrds*simple</Type>
<!-- OpenID Consumer Service -->
<Service priority="10">
<Type>http://specs.openid.net/auth/2.0/return_to</Type>
<URI>https://goff.wpengine.com/index.php/openid/consumer</URI>
</Service>
<!-- OpenID Provider Service (0) -->
<Service priority="0">
<Type>http://specs.openid.net/auth/2.0/server</Type>
<URI>https://goff.wpengine.com/index.php/openid/server</URI>
<LocalID>http://specs.openid.net/auth/2.0/identifier_select</LocalID>
</Service>
<!-- AtomPub Service -->
<Service priority="10">
<Type>http://www.w3.org/2007/app</Type>
<MediaType>application/atomsvc+xml</MediaType>
<URI>https://goff.wpengine.com/wp-app.php/service</URI>
</Service>
</XRD>
I have verified that the OpenID provider works by using it to log in to other OpenID enabled sites, including other Wordpress installs with the OpenID plugin and Stackoverflow.
When using the login link http://api.lighthouseuk.net/_ah/login_redir?claimid=https://goff.wpengine.com/?xrds&continue=http://api.lighthouseuk.net/ GAE returns a HTTP 500 error after several seconds. We haven't found any reason for this - there are no log entries in the admin console - but I suspect it may have something to do with the configuration on wpengine.com not returning the XRDS file or caching an incorrect one.
We have semi-confirmed this by running an identical setup on our dev server which has no caching enabled. Now when we visit the login link GAE returns a HTTP 302 response followed by a HTTP 204 response: http://www.google.com/gen_204?reason=EmptyURL.
As far as I can tell, after requesting the XRDS file GAE makes no further requests to our server. This leads me to believe that there might be a problem with the XRDS file but I can't find any details in the documentation about required attributes.
Things tried:
Login on other systems
If you send an authentication request to the URI specified in the XRDS document the OpenID server responds correctly by prompting the user to log in. Again this suggests that GAE takes issues with the XRDS file because no authentication request is made to our server. I can't figure out how to debug it when there are no errors recorded in the logs.
e.g. https://goff.wpengine.com/openid/server?openid.ns=http://specs.openid.net/auth/2.0&openid.claimed_id=http://specs.openid.net/auth/2.0/identifier_select&openid.identity=http://specs.openid.net/auth/2.0/identifier_select
&openid.return_to=http://api.lighthouseuk.net/checkauth&openid.realm=http://api.lighthouseuk.net/&openid.mode=checkid_setup
SSL
Obviously for a production environment we would be using SSL on both Wordpress and GAE but currently this is just a proof of concept. cURL, by default I believe, attempts to check the validity of SSL certificates so we've tried various combinations of SSL setting, including having none at all. Seemingly no effect.
Wordpress permalinks
As the XRDS document, by default, points to /index.php/openid/server/ we attempted different combinations of permalink setting in Wordpress to see if it had any effect. It didn't.
URL encode
URL encoding the claimid seemed to have no effect - we still received the HTTP 204 response.
After giving up for a while I revisited this issue and managed to solve it. Answering here in case anyone else faces the same issues. Ultimately it was down to my use of secure URLs.
TL;DR
It should have been the first thing I checked but, make sure you have an SSL certificate on your server so that the OpenID server is accessible via a secure URL. You will get a HTTP 500 error from GAE if the URL is not secure or if the SSL certificate does not validate (Obvious in hindsight but, this caught me out on a different test site with a custom generated SSL certificate).
In addition, make sure that the XRDS document contains said secure address in the <URI> element.
Setup Details
Using OpenID plugin Version 3.3.4
Using XRDS-Simple plugin Version 1.1
Wordpress version 3.8
Hosted on WPEngine.com
Google App Engine instance running the gae-boilerplate code (federated identity enabled)
Modifications
I played around with fiddler2 to see if I could learn anything more about the requests made to and from GAE. I compared the access logs from my OpenID server on WPEngine with the data I could pull from fiddler2 about the stackexchange OpenID server (openid.stackexchange.com).
XRDS-Simple Plugin
I modified this plugin to include an additional filter for the Wordpress HTTP headers:
add_filter('wp_headers', 'xrds_add_xrds_location');
function xrds_add_xrds_location($headers) {
error_log('Adding XRDS header', 0);
$headers['X-XRDS-Location'] = get_bloginfo('url').'/?xrds';
return $headers;
}
After that I modified the xrds_write() function to simply return the following xml:
<?xml version="1.0" encoding="UTF-8"?>
<xrds:XRDS
xmlns:xrds="xri://$xrds"
xmlns:openid="http://openid.net/xmlns/1.0"
xmlns="xri://$xrd*($v*2.0)">
<XRD>
<Service priority="10">
<Type>http://specs.openid.net/auth/2.0/server</Type>
<Type>http://openid.net/extensions/sreg/1.1</Type>
<Type>http://axschema.org/contact/email</Type>
<URI>http://goff.wpengine.com/index.php/openid/server</URI>
</Service>
</XRD>
</xrds:XRDS>
This got rid of the http://www.google.com/gen_204?reason=EmptyURL redirect and simply returned a HTTP 500 error.
Curious, I tried various different things to get any response out of GAE (remember GAE does not show error that occur in the /_ah/ handlers.
As a last resort I modified the <URI> element to be https instead of http. This did the trick! I was successfully redirected to goff.wpengine.com and was asked to verify that I wanted to login. Excited, I clicked verify. PHP Fatal error: Call to a member function needsSigning() on a non-object. Balls. At least now I could ascertain problems from the PHP error log.
OpenID Plugin
After some quick Googling I found a thread on Google Code for the OpenID plugin. People had had similar issues and the consensus was that it was due to a plugin conflict. Comment #55 from user infinite.alis mentioned that adding the Relying Party to the user's 'Trusted Sites' consistently solved the problem. Lo and behold, after adding the address to my trusted sites the entire authentication flow completed without error!
Conclusion
I have yet to do a post mortem to figure out which of the changes to XRDS-Simple made the difference. I suspect that simply changing the <URI> element in XRDS-Simple to https would solve the problem (My previous tests with SSL only focused on making sure the users.create_login_url() function was passed a secure address, not that the XRDS file described the OpenID server via a secure address). Possibly need to play around with the filters for get_bloginfo('url') in the xrds_write() function.

Resources