How to use Facebook OAuth2 with 2FA - facebook

Is there a way to add 2FA to Facebook's Oauth2 flow? The following error is returned when trying to hit the graph API's insights endpoint for a user that has 2FA enabled on their FB Business Manager account:
"error": {
"fbtrace_id": "HrY8K9KfT4U",
"error_user_msg": "Unknown error",
"message": "Two factor authentication required. User have to enter a code from SMS or TOTP code generator to pass 2fac. This could happen when accessing a 2fac-protected asset like a page that is owned by a 2fac-protected business manager.",
"error_subcode": 1404120,
"type": "OAuthException",
"error_user_title": "Ask user to pass two factor authentication",
"is_transient": false,
"code": 415
}

I've seen this issue a couple of times and the problem usually extends from the Business Manager having two-factor authentication enabled, but the user making the API calls does not have two-factor authentication enabled on their account.
In all the cases I've seen, having the user enable two-factor authentication on their account, and pass through the 2-fac login flow has fixed the issue for the user.

Related

Using OAuth2 for sending email with smtp and gmail

I want to send emails with java and smtp using OAuth2 access_token
I am able to do it if I use OAuth2 type that prompts the user with a browser to allow access.
Now I want to use a google service account and send a jwt json file to get the access token
As documented here
https://developers.google.com/identity/protocols/oauth2/service-account
I get a response back from the token url (https://oauth2.googleapis.com/token) that has a access_token, but it does not return a scope attribute and also has a ton of trailing periods
When I use it to call the smtp it responds with a 400 error
My Question is does gmail api work with jwt tokens?
Do I need to also have a Google Workspace Account or can I just use a normal Gmail Account?
EDIT FOLLOW UP:
I called the token validator url and got this back
https://www.googleapis.com/oauth2/v1/tokeninfo?access_token=xxx
validateAccessToken response: {
"issued_to": "xxx",
"audience": "xxx",
"scope": "https://mail.google.com/",
"expires_in": 3599,
"access_type": "online"
}
Not sure if it is the issue but access_type = "online" instead of offline like when I do it with 3 leg auth that requires user approval for access. Doing the JWT way I do not see anywhere to define access_type when requesting token

PayPal REST API: Make requests on behalf of a merchant

I'm in the process of migrating our software, which makes requests on behalf of merchants to PayPal using the PayPal SOAP API, to the PayPal REST API infrastructure.
I'm using the Client ID / Secret of my PayPal developer account to get a Bearer token from the Sandbox, using https://api.sandbox.paypal.com/v1/oauth2/token.
Then I'm doing a call to https://api.sandbox.paypal.com/v2/checkout/orders, using our the bearer token just got, to make requests on behalf of a merchant. I'm using the PayPal-Auth-Assertion header with the following (encoded) JWT-Token:
Header:
{
"typ": "JWT",
"alg": "HS256"
}
Body: {
"email": "[merchant e-mail]",
"iss": "[my client id]"
}
The "merchant e-mail" is one of the sandbox accounts I opened in https://developer.paypal.com/developer/accounts/
In return I get a (400) Bad Request {"error":"invalid_request","error_description":"No permissions to set target_client_id"}.
It seems like there must be an additional step for the sandbox account to grant permissions to the developer account. For the SOAP API, I could add the user name of a 3rd party in the following screen . Then I could use the same username as header value for X-PAYPAL-SECURITY-USERID. However, I cannot seem to link the sandbox account in the same way, because there is no "third party username" for the main account (the one I'm getting the Client ID from).
What exactly has to be configured to allow these types of 3rd party calls for REST API?
I'm using the PayPal-Auth-Assertion header with the following (encoded) JWT-Token:
You need to be a PayPal partner to be using that type of functionality. Contact PayPal if you want to be a partner.
If you want to use their generally-accessible APIs, you have two options.
Have every merchant create their own REST API App via https://www.paypal.com/signin?intent=developer&returnUri=https%3A%2F%2Fdeveloper.paypal.com%2Fdeveloper%2Fapplications , and copy paste their live client ID and secret into your configuration. This is the best solution, and it is the solution you should pursue.
Use the payee object: https://developer.paypal.com/docs/checkout/integration-features/custom-payee/ , which gives you less control (cannot capture authorizations or issue refunds, for example)

How to authenticate for Facebook graph API using standard OAuth 2.0 libraries?

In a project I am using Authentication multiple times for different providers, so I am relying on standard libraries.
I want to establish connection with Facebook yet it provides not completely standard authorization.
To test the connection I am using REST Console in Authorization part of it I place a key and secret and for
Authorize URL I provide https://graph.facebook.com/oauth/authorize
Access token URL - https://graph.facebook.com/oauth/access_token
Request token URL I leave empty or fill it with https://graph.facebook.com/
And what I get bck looks like this:
{
"error": {
"message": "Expected 1 '.' in the input between the postcard and the payload",
"type": "OAuthException",
"code": 1
}
}
So my question is how to get authenticated forming standard OAuth calls?
EDIT
For the moment (testing stage) I found that data can be retrieved using no standard authentication but access_token with appropriate values. Yet sending http request with api key and secret exposed in the request url can not be the right way of ding it.

sending a facebook_question to other users

With Facebook, I can successfully send a question to myself using /me/questions?question=question&options=["answer1","answer2"].
But I can not send a question to another user. With another user's ID instead of "me" I get an error:
{
"message": "(#240) Requires a valid user is specified (either via the session or via the API parameter for specifying the user.",
"type": "OAuthException",
"code": 240
}
Basically you need a token that incorporates the publish_stream permission for the specified user id. See:
https://developers.facebook.com/docs/reference/api/user/#questions

FaceBook Auth and signed request

on the client side I am using the flash API to sign in and auth the client
Facebook.init(MyFaceBooyKey, faceBookInit);
Then face book sends back to the client a Signed Request and other stuff.
I the client then sends this signed request to my server.
On my server I process the Signed Request and out pops a FaceBook User id (UID)
So now I am assuming that:
The client who sent the valid signed request is the owner of the Face book UID contained inside it, the client must know the password for that UID, and they are loged into facebook ?
Is this system safe ?
how can i safely use user client side facebook auth to then autho in to a second server, eg a sepreak facebook game server.
How can I make suer that the signed reques has not been coped in transit on the web,
and then sent to me by a thirs party, who now logs on to my server under a Uiffrent UID
How to all theas flash based facebook games auth the users ?
also I note that the same book auth vias the Desktop application dose not send a signed reques ? so how to do the auth to my server in this case ?
All of the auth flows with facebook use SLL (https) and so the data you send/get is secured.
The same goes for all of the graph api requests, if you try to make an api request in http while including an access token you'll get this response:
{
"error": {
"message": "You must use https:// when passing an access token",
"type": "OAuthException",
"code": 1
}
}
If you send the signed request and/or the access token to your server then you should do it by https as well and that way that communication will also be secured.
The client (and I assume you meany the flash client) is not the "owner" of the access token/signed request, your app is the "owner".
If you need the access token on the server side I suggest that you use the Server-Side Auth flow to get it.
If you then need the access token on the client side then you can use a client side auth, since the user already authorized the app and authenticated for sure (through the server side flow) the client side process should be completely invisible for the user, and at the end of it you'll have an access token on the client side as well (a different one than on the server).
"message": "You must use https:// when passing an access token",
"type": "OAuthException",
"code": 1
}
} "message": "You must use https:// when passing an access token",
"type": "OAuthException",
"code": 1
}
} "message": "You must use https:// when passing an access token",
"type": "OAuthException",
"code": 1
}
}