Why is my Facebook application with error 104 ("invalid signature")? - python

I am trying to develop a Facebook application using PyFacebook (hosted on Google App Engine). It's an FBML application (runs in a Facebook canvas instead of an iframe). I'm having problems getting any API calls to function. The sequence looks like this:
fb = facebook.Faceboook(api_key, secret_key)
fb.session_key = cherrypy.request.params['fb_sig_session_key']
fb.uid =cherrypy.request.params['fb_sig_user']
Then if I try, for example:
user = fb.users.getLoggedInUser()
This will fail with:
Error 104: Incorrect signature
I'm not sure where I'm going wrong. I've verified that the api_key and secret_key are correct (many, many times). The application has been added to my account. I've even been able to get a desktop application working; my problem is only with this web-hosted version.
Thanks for your help!

Deleting the Facebook application and re-creating it, then configuring my code with the new API key and secret key, resolved this problem.

Related

EasyAuth on Azure Function App errors out custom oidc provider

We have a Python Linux azure function that is connected to a custom oidc provider and azure ad to provide authentication to the HTTP triggered functions using Microsofts easyauth.
After the initial setup, the azure function was working and has been working for the last few months.
In the last 2 days, our application suddenly started to error out on our custom provider, the azure ad authentication is still working, after checking the easyauth logs, we see the error
System.PlatformNotSupportedException: Windows Cryptography Next Generation (CNG) is not supported on this platform.
No changes were made on either the custom oidc provider or the azure function in the last 2 days.
We suspect that maybe the base easyauth docker image (mcr.microsoft.com/appsvc/middleware:stage2) got updated and that broke the authentication.
Any ideas or suggestions on possible fixes or even related problems?
Could it be due to this: https://github.com/Azure/app-service-announcements/issues/404
Use RSACNG when validating tokens to add PS256 support
EDIT: Also experiencing this issue as of this morning. I'm currently trying to manually downgrade the version using this command az webapp auth update --name xxx --resource-group xxx --runtime-version "1.5.1" but my Azure credentials don't have enough power to run that so I can't validate if it works or not.
EDIT2: Doesn't work if you are using auth v2.
EDIT3: It actually does work if you are using auth v2. You just have to check the help options of the command to realize that for auth v2 you have to install a CLI extension with command az extension add --name authV2. After that you can run the commands. I downgraded the version to 1.5.1 but nothing changed. I'm not sure if it has something to do with the fact that we are deploying to a slot first which probably had the new version still. I have also created an Azure support ticket about this.
EDIT4: Got in to a support call with Azure yesterday. They fixed the issue during the night. A restart of the application is required. I'm still baffled by the fact that the documentation shows that you can pinpoint the version of Easy Auth / Authentication/Authorization middleware but when I go to troubleshoot my AppService and select Easy Auth it actually shows that the pinpointed version is 1.5.1 and the running version is 1.6.2. So it just totally ignores the whole configuration. Fun, right?
we have started to see this as well on some of our instances, the worrying thing is that we have multiple running instances and it is working in some and not in some.
we "solved" the issue on one production instance by redeploying the function app, it is setup through terraform and a destroy of the function app and then a create made it work again.
Exact same issue there.
2 app services (one for prod and one for dev located in France central region) using an Azure AD app in an other Azure B2C tenant for authentication (https://learn.microsoft.com/en-us/azure/app-service/configure-authentication-provider-aad#-option-2-use-an-existing-registration-created-separately) were working for about 1 year.
Then after the deployment of a new container version of our app in the "dev" app service, the authentication broke en DEV only and we started receiving ERROR 500 message when we are being redirected to the /.auth/login/aad/callback endpoint after the authentication is done in Azure B2C.
By inspecting the app service log we have these logs :
2022-11-08T08:47:28.449645417Z [41m[30mfail[39m[22m[49m: Microsoft.AspNetCore.Server.Kestrel[13]
**2022-11-08T08:47:28.449692217Z Connection id "0HMM1CIPP8I5M", Request id "0HMM1CIPP8I5M:00000004": An unhandled exception was thrown by the application**.
2022-11-08T08:47:28.450647224Z System.PlatformNotSupportedException: Windows Cryptography Next Generation (CNG) is not supported on this platform.
2022-11-08T08:47:28.451187128Z at System.Security.Cryptography.RSACng..ctor()
2022-11-08T08:47:28.451205328Z at Microsoft.Azure.AppService.Middleware.JsonWebKey.GetSecurityKeys() in /EasyAuth/Microsoft.Azure.AppService.Middleware.Modules/JsonWebKey.cs:line 100
2022-11-08T08:47:28.451422129Z at Microsoft.Azure.AppService.Middleware.OpenIdConnectConfiguration.GetJwtValidationParameters(String siteName, String clientId, String authenticationType, String allowedAudiences) in /EasyAuth/Microsoft.Azure.AppService.Middleware.Modules/OpenIdConnectConfiguration.cs:line 114
2022-11-08T08:47:28.457668471Z at Microsoft.Azure.AppService.Middleware.AzureActiveDirectoryProvider.GetOpenIdConnectValidationParameters(ConfigManager oidcConfigManager, Boolean forceRefresh) in /EasyAuth/Microsoft.Azure.AppService.Middleware.Modules/IdentityProviders/AzureActiveDirectoryProvider.cs:line 1131
2022-11-08T08:47:28.457685071Z at Microsoft.Azure.AppService.Middleware.AzureActiveDirectoryProvider.HandleServerDirectedLoginAsync(HttpContextBase context) in /EasyAuth/Microsoft.Azure.AppService.Middleware.Modules/IdentityProviders/AzureActiveDirectoryProvider.cs:line 518
2022-11-08T08:47:28.457689872Z at Microsoft.Azure.AppService.Middleware.IdentityProviderBase.OnCompleteServerDirectedLoginAsync(HttpContextBase context) in /EasyAuth/Microsoft.Azure.AppService.Middleware.Modules/IdentityProviders/IdentityProviderBase.cs:line 655
2022-11-08T08:47:28.457693772Z at Microsoft.Azure.AppService.Middleware.IdentityProviderBase.TryHandleProtocolRequestAsync(HttpContextBase context) in /EasyAuth/Microsoft.Azure.AppService.Middleware.Modules/IdentityProviders/IdentityProviderBase.cs:line 185
2022-11-08T08:47:28.457697572Z at Microsoft.Azure.AppService.Middleware.EasyAuthModule.OnBeginRequestAsync(HttpContextBase context) in /EasyAuth/Microsoft.Azure.AppService.Middleware.Modules/EasyAuthModule.cs:line 220
2022-11-08T08:47:28.457818072Z at Microsoft.Azure.AppService.Middleware.NetCore.AppServiceMiddleware.InvokeAsync(HttpContext context) in /EasyAuth/Microsoft.Azure.AppService.Middleware.NetCore/AppServiceMiddleware.cs:line 102
2022-11-08T08:47:28.457928173Z at Microsoft.Azure.AppService.MiddlewareShim.AutoHealing.AutoHealingMiddleware.Invoke(HttpContext context) in /EasyAuth/Middleware.Host/AutoHealing/AutoHealingMiddleware.cs:line 55
2022-11-08T08:47:28.457939473Z at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpProtocol.ProcessRequests[TContext](IHttpApplication`1 application)
Creating a new app in an other app service plan did not improve the situation so we have opened a support ticket/case at Microsoft. This issue has nothing to do with our application.This issue is 100% related to a change that might happened at Microsoft.
Let's keep in touch on this thread to share knowledge about this issue.
issue is solved after restarting the azure app services

How to disable caching for Adwords API on App Engine with zeep?

I am trying to disable caching with zeep as is described here:
https://github.com/googleads/googleads-python-lib/blob/master/README.md#how-can-i-configure-or-disable-caching
adwords_client = adwords.AdWordsClient(
developer_token, oauth2_client, user_agent,
client_customer_id=client_customer_id,
cache=googleads.common.ZeepServiceProxy.NO_CACHE)
But I lack understanding of what I should provided ot AdWordsClient as ‘oauth2_client’ attribute.
I am trying to find the solution here http://googleads.github.io/googleads-python-lib/googleads.oauth2.GoogleOAuth2Client-class.html but without success so far.
I am using For OAuth2 process google_auth_oauthlib and I managed retrieved refresh token, but at this point I am kinda lost, because due to the fact that I am running it on GCP App Engine, I am not able to use googleads.yaml file.
Can somebody enlighten me in a case of this oauth2_client?
Thanks sincerely!
A bit late but I found a solution to this and wanted to share with anyone who might hit this question.
Here's where I found the solution
You can do LoadFromStorage then disable the zeep cache:
from googleads import ad_manager, common
client = ad_manager.AdManagerClient.LoadFromStorage()
client.cache = common.ZeepServiceProxy.NO_CACHE
I spent hours trying to load using the credentials, and couldn't get it to work. This allowed me to run the module from an EC2 instance.
here is an example of using Google Ads Python Client Library on an Google App Engine App.
In this example it is explained how to do all the process for authentication considering there is no googleads.yaml
In particular for the oauth2_client check here they generate it like this:
oauth2credentials = client.OAuth2Credentials(
None, args.client_id, args.client_secret, args.refresh_token,
datetime.datetime(1980, 1, 1, 12), GOOGLE_OAUTH2_ENDPOINT,
USER_AGENT)
GOOGLE_OAUTH2_ENDPOINT is 'https://accounts.google.com/o/oauth2/token'
and USER_AGENT is given to you in the Adwords API information

Unable to switch gcloud platform account using python script

Please could someone help me with a query related to permissions on the Google cloud platform? I realise that this is only loosely programming related so I apologise if this is the wrong forum!
I have a project ("ProjectA") written in Python that uses Googles cloud storage and compute engine. The project has various buckets that are accessed using python code from both compute instances and from my home computer. This project uses a service account which is a Project "owner", I believe it has all APIs enabled and the project works really well. The service account name is "master#projectA.iam.gserviceaccount.com".
Recently I started a new project that needs similar resources (storage, compute) etc, but I want to keep it separate. The new project is called "ProjectB" and I set up a new master service account called master#projectB.iam.gserviceaccount.com. My code in ProjectB generates an error related to access permissions and is demonstrated even if I strip the code down to these few lines:
The code from ProjectA looked like this:
from google.cloud import storage
client = storage.Client(project='projectA')
mybucket = storage.bucket.Bucket(client=client, name='projectA-bucket-name')
currentblob = mybucket.get_blob('somefile.txt')
The code from ProjectB looks like this:
from google.cloud import storage
client = storage.Client(project='projectB')
mybucket = storage.bucket.Bucket(client=client, name='projectB-bucket-name')
currentblob = mybucket.get_blob('somefile.txt')
Both buckets definitely exist, and obviously if "somefile.text" does not exist then currentblob is None, which is fine, but when I execute this code I receive the following error:
Traceback (most recent call last):
File .... .py", line 6, in <module>
currentblob = mybucket.get_blob('somefile.txt')
File "C:\Python27\lib\site-packages\google\cloud\storage\bucket.py", line 599, in get_blob
_target_object=blob,
File "C:\Python27\lib\site-packages\google\cloud\_http.py", line 319, in api_request
raise exceptions.from_http_response(response)
google.api_core.exceptions.Forbidden: 403 GET https://www.googleapis.com/storage/v1/b/<ProjectB-bucket>/o/somefile.txt: master#ProjectA.iam.gserviceaccount.com does not have storage.objects.get access to projectB/somefile.txt.
Notice how the error message says "ProjectA" service account doesn't have ProjectB access - well, I would somewhat expect that but I was expecting to use the service account on ProjectB!
Upon reading the documentation and links such as this and this, but even after removing and reinstating the service account or giving it limited scopes it hasnt helped. I have tried a few things:
1) Make sure that my new service account was "activated" on my local machine (where the code is being run for now):
gcloud auth activate-service-account master#projectB.iam.gserviceaccount.com --key-file="C:\my-path-to-file\123456789.json"
This appears to be successful.
2) Verify the list of credentialled accounts:
gcloud auth list
This lists two accounts, one is my email address (that I use for gmail, etc), and the other is master#projectB.iam.gserviceaccount.com, so it appears that my account is "registered" properly.
3) Set the service account as the active account:
gcloud config set account master#projectB.iam.gserviceaccount.com
When I look at the auth list again, there is an asterisk "*" next to the service account, so presumably this is good.
4) Check that the project is set to ProjectB:
gcloud config set project projectB
This also appears to be ok.
Its strange that when I run the python code, it is "using" the service account from my old project even though I have changed seemingly everything to refer to project B - Ive activated the account, selected it, etc.
Please could someone point me in the direction of something that I might have missed? I don't recall going through this much pain when setting up my original project and Im finding it so incredibly frustrating that something I thought would be simple is proving so difficult.
Thank you to anyone who can offer me any assistance.
I'm not entirely sure, but this answer is from a similar question on here:
Permission to Google Cloud Storage via service account in Python
Specifying the account explicitly by pointing to the credentials in your code. As documented here:
Example from the documentation page:
def explicit():
from google.cloud import storage
# Explicitly use service account credentials by specifying the private key
# file.
storage_client = storage.Client.from_service_account_json(
'service_account.json')
# Make an authenticated API request
buckets = list(storage_client.list_buckets())
print(buckets)
Don't you have a configured GOOGLE_APPLICATION_CREDENTIALS env variable which points project A's SA?
The default behavior of Google SDK is to takes the service account from the environment variable GOOGLE_APPLICATION_CREDENTIALS.
If you want to change the account you can do something like:
from google.cloud import storage
credentials_json_file = os.environ.get('env_var_with_path_to_account_json')
client= storage.Client.from_service_account_json(credentials)
The above assumes you have creates a json account file like in: https://cloud.google.com/iam/docs/creating-managing-service-account-keys
and that the json account file is in the environment variable env_var_with_path_to_account_json
This way you can have 2 account files and decide which one to use.

Unauthenticated error using gcloud-python to connect to google bigtable

I've set up a Google Cloud BigTable cluster on my project. The main codebase for the project runs within a standard Python App Engine environment, which can't use the gcloud-python library because of the reliance on grpcio. To get around this, I've set up a Python App Engine Flexible Environment service within the same project and written a very simple Flask server to run on it, which I can then hit from my standard environment. The code looks something like this:
from gcloud import bigtable
app = Flask(__name__)
client = bigtable.Client(project=bigtable_config.PROJECT_ID, read_only=True)
cluster = client.cluster(bigtable_config.ZONE_ID, bigtable_config.CLUSTER_ID)
table = cluster.table(bigtable_config.TABLE_ID)
#app.route("/query/<start_key>/<end_key>")
def run_query(start_key, end_key):
if not client.is_started():
client.start()
row_data = table.read_rows(start_key=start_key, end_key=end_key)
row_data.consume_all()
// do some stuff to the row data here, get results
return jsonify(results)
I can run this code locally and it works great. I can deploy it to my service and it continues to work great. However, if the service sits idle for some period of time (I've typically noticed it after about an hour), then every request I make starts failing with this error:
NetworkError(code=StatusCode.UNAUTHENTICATED, details="Request had invalid authentication credentials.")
If I redeploy the service, it starts working again. I do not observe this behavior when I'm running the service locally.
What am I doing wrong? I'm assuming I'm making some mistake in my setup of the client, where it's not properly using the app engine credentials. Do I need to kill the client and restart it when I encounter this error?
This issue is being tracked at github.

is my google app engine deployed source code secure?

I'm thinking about good ways to store third party credentials, which basically means there needs to be a secret somewhere, either in code or data. I'm deploying on google app engine.
If the 'secret' was something like
pw_passphrase = sha2(username + 'global-password')
pw_plaintext = aes_decrypt(pw_passphrase, pw_ciphertext)
can I depend on this code never being seen by a non appengine administrator?
...what if the credentials protect something supersensitive like personal financial data, do we still trust it?
(The sha2 bit is exchangable with any other secret pseudo-random function.)
Yes: your source code is secure (as secure as Google can make it), and there's no way for unauthorized third parties to peek.
Also remember to handle exceptions in your code with an error page, or else an exception thrown might uncover your source code to an unsigned user.

Categories