Facebook4j access token error 2500 - java

I would like get data from facebook with facebook4j library, but I received this error
An active access token must be used to query information about the
current user. code - 2500
The code:
ConfigurationBuilder confBuilder = new ConfigurationBuilder();
confBuilder.setDebugEnabled(true);
confBuilder.setOAuthAppId("MY ID APP");
confBuilder.setOAuthAppSecret("MY APP SECRET");
confBuilder.setUseSSL(true);
confBuilder.setJSONStoreEnabled(true);
Configuration configuration = confBuilder.build();
FacebookFactory facebookFactory = new FacebookFactory(configuration );
Facebook facebookClient = facebookFactory.getInstance();
AccessToken accessToken = null;
OAuthSupport oAuthSupport = new OAuthAuthorization(configuration );
accessToken = oAuthSupport.getOAuthAppAccessToken();
facebookClient.setOAuthAccessToken(accessToken);
ResponseList<Post> feeds = facebookClient.getHome(new Reading().limit(1000));

You go to the following link: https://developers.facebook.com/tools/explorer/
There you choose your app, which you created and want to access from.
.setOAuthAccessToken("The User Access Token")
accessToken = oAuthSupport.getOAuthAccessToken(); // NOT AppAccessToken!!!
Then it should work

Related

Error code AADSTS70000121 when using One Drive through Microsoft Graph in Java

I have a Java application that integrates with One Drive through Microsoft Graph. I followed the documentation and I am able to pass the authorisation step but when interrogating the API I get this error:
"AADSTS70000121: The passed grant is from a personal Microsoft account and is required to be sent to the /consumers or /common endpoint."
What am I missing?
This is the code I am using:
Get an authorisation token using the URL bellow
private static final String RESPONSE_TYPE = "code";
private static final String SCOPE = "openid%20Files.Read%20Files.ReadWrite%20Contacts.Read%20offline_access";
String authorizeUrl = "https://login.microsoftonline.com/common/oauth2/v2.0/authorize?client_id=" + CLIENT_ID
+ "&scope=" + SCOPE + "&response_type=" + RESPONSE_TYPE + "&redirect_uri=" + REDIRECT_URL;
Exchange the received authorization token
List<String> scopes = new LinkedList<String>();
scopes.add("https://graph.microsoft.com/.default");
AuthorizationCodeCredential authCodeCredential = new AuthorizationCodeCredentialBuilder()
.clientId(CLIENT_ID)
.clientSecret(CLIENT_SECRET)
.authorizationCode(authorizationCode)
.redirectUrl(REDIRECT_URL)
.build();
TokenCredentialAuthProvider tokenCredAuthProvider = new TokenCredentialAuthProvider(scopes, authCodeCredential);
GraphServiceClient graphClient = GraphServiceClient.builder().authenticationProvider(tokenCredAuthProvider).buildClient();
User me = graphClient.me()
.buildRequest()
.get();
As you are using the personal account then please change the endpoint to consumers instead of common,
https://login.microsoftonline.com/consumers/oauth2/v2.0/authorize?
ref doc - https://learn.microsoft.com/en-au/azure/active-directory/develop/v2-oauth2-auth-code-flow
Hope this helps
Thanks

Error while creating google calendar event with a service account

I have a requirement of creating a google calendar event on a calendar and add other users as attendees to that event. The objective is to send calendar events to the application users without taking their consent ( O-Auth ).
After reading Google's documentation, I found out that I need a service account. So I created a project and a service account from one of the email addresses of our G-Suite, noreply#xxxxx.com and enabled calendar API for the same.
I created and downloaded a key pair ( JSON ) whose content is,
{
"type": "service_account",
"project_id": "*****",
"private_key_id": "bdbbcd**************49f77d599f2",
"private_key": "**"
"client_email": "******#*****.iam.gserviceaccount.com",
"client_id": "11083******576856",
"auth_uri": "https://accounts.google.com/o/oauth2/auth",
"token_uri": "https://oauth2.googleapis.com/token",
"auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
"client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/****dev%40*****kdev.iam.gserviceaccount.com"
}
And as per the documentation, I proceded to write authentication flow code,
public static GoogleCredential doOauth( String credsPath ) throws IOException
{
GoogleCredential credential = GoogleCredential.fromStream(new FileInputStream(credsPath))
.createScoped(Collections.singleton(CalendarScopes.CALENDAR));
System.out.println(credential);
return credential;
}
The credential object has most of the details from the key file. But, the fields, serviceAccountUser, accessToken, refreshToken, clientAuthentication and requestInitializer have null value. ( I am guessing something wrong here )
Now, using the credentialObject, I continued to write the code as per the documentation to create the event.
GoogleCredential credential = doOauth(CREDENTIALS_FILE_PATH);
Event event = new Event().setSummary("Google I/O 2015").setLocation("800 Howard St., San Francisco, CA 94103")
.setDescription("A chance to hear more about Google's developer products.");
final NetHttpTransport HTTP_TRANSPORT = GoogleNetHttpTransport.newTrustedTransport();
DateTime startDateTime = new DateTime("2020-12-28T09:00:00-07:00");
EventDateTime start = new EventDateTime().setDateTime(startDateTime).setTimeZone("America/Los_Angeles");
event.setStart(start);
DateTime endDateTime = new DateTime("2020-12-28T17:00:00-07:00");
EventDateTime end = new EventDateTime().setDateTime(endDateTime).setTimeZone("America/Los_Angeles");
event.setEnd(end);
String[] recurrence = new String[] { "RRULE:FREQ=DAILY;COUNT=2" };
event.setRecurrence(Arrays.asList(recurrence));
EventAttendee[] attendees = new EventAttendee[] { new EventAttendee().setEmail("myemailaddress#gmail.com.com") };
event.setAttendees(Arrays.asList(attendees));
EventReminder[] reminderOverrides = new EventReminder[] {
new EventReminder().setMethod("email").setMinutes(24 * 60),
new EventReminder().setMethod("popup").setMinutes(10), };
Event.Reminders reminders = new Event.Reminders().setUseDefault(false)
.setOverrides(Arrays.asList(reminderOverrides));
event.setReminders(reminders);
String calendarId = "primary";
Calendar service = new Calendar.Builder(HTTP_TRANSPORT, JSON_FACTORY, credential)
.setApplicationName("testapp").build();
event = service.events().insert(calendarId, event).execute();
System.out.printf("Event created: %s\n", event.getHtmlLink());
But, this resulted in the error,
{
"code" : 403,
"errors" : [ {
"domain" : "calendar",
"message" : "Service accounts cannot invite attendees without Domain-Wide Delegation of Authority.",
"reason" : "forbiddenForServiceAccounts"
} ],
"message" : "Service accounts cannot invite attendees without Domain-Wide Delegation of Authority."
}
After spending time on Domain-Wide Delegation, I understood that this is needed if we have to send the event as other user from our g-suite, which is not needed for my problem. But, to debug, I went ahead and provided Domain-Wide Delegation and re ran the program. The same error came again.
So, I removed the invitees/attendees from the event object and re ran the application. This time the program ran without any error, but the event link generated, on click says, Could not find the requested event.
I do not see any examples of using the service account via java client libraries on the google developer link.
Can you please let me know what is going wrong here and the official/working documentation on how exactly to create a google calendar event from my project add other ( non g suite as well ) users to add as attendees, so that I do not have to get consent from other users to add events to their own calendar?
Thank You.
Fist off I want to say that this is something new, if you are seeing a lot of questions, and tutorials that did not state you needed to do this its because service accounts used to be able to send invites, this is something google locked down about a year ago.
This should work but i have not tested it as i no longer have access to a Gsuite account. You need to have the gsuite admin set up domain wide delegation to anther user. Then the service account needs to impersonate that user so it will appear as that user is the one sending the invites.
The only example I have for how that is added is in .net
.net example
var gsuiteUser = "se#clawskeyboard.com";
var serviceAccountCredentialInitializer = new ServiceAccountCredential.Initializer(serviceAccount)
{
User = gsuiteUser,
Scopes = new[] { GmailService.Scope.GmailSend, GmailService.Scope.GmailLabels }
}.FromCertificate(certificate);
Java example guess
I am not a java dev but the .net client library and the Java client library are very close in how they were developed. I would guess that you are looking for a method called setServiceAccountUser
GoogleCredential credential = new GoogleCredential.Builder().setTransport(HTTP_TRANSPORT)
.setJsonFactory(JSON_FACTORY)
.setServiceAccountId(SERVICE_ACCOUNT_EMAIL)
.setServiceAccountScopes(CalendarScopes.CALENDAR)
.setServiceAccountPrivateKeyFromP12File(credsPath))
.setServiceAccountUser(gsuiteUser)
.build();
OAuth2 for Service Accounts
You should be able to impersonate the account user by setting the delegated variable to the user's email in the GoogleCredential object.
GoogleCredential credential = GoogleCredential.fromStream(new FileInputStream("credentials.json"))
.createScoped(<SCOPES>)
.createDelegated("user#example.com");

Obtain Facebook Events using restfb

I need to obtain all public events from my fb page.
It's not possible using an App access token anymore: "Requires a valid Page or User access token with basic permissions." - https://developers.facebook.com/docs/graph-api/reference/page/events/
I don't want to put my User credentials into my Application.
Current code:
FacebookClient.AccessToken accessToken = new DefaultFacebookClient(Version.LATEST).obtainAppAccessToken(facebookProperties.getAppId(), facebookProperties.getAppSecret());
FacebookClient facebookClient = new DefaultFacebookClient(accessToken.getAccessToken(), Version.LATEST);
Date now = new Date();
Connection<com.restfb.types.Event> eventConnection = facebookClient.fetchConnection(facebookProperties.getPageId() + "/events", com.restfb.types.Event.class, Parameter.with("fields", "name,start_time"));
List<Event> events = eventConnection.getData().stream().filter(facebookEvent -> now.compareTo(Optional.ofNullable(facebookEvent.getEndTime()).orElse(facebookEvent.getStartTime())) <= 0).map(facebookEvent -> Event.fromFacebookEvent(facebookEvent)).collect(Collectors.toCollection(LinkedList::new));
A dirty Workaround would be creating a new fb account, adding it as a Page admin and provide its Credentials. Is there a better way to simply obtain the public Events?

How to create bulkconnection with accesstoken in salesforce

I need to create BulkConnection for bulk API into salesforce.
We can able to create BulkConnection using ConnectorConfig with basic SOAP authentication.
Code is below,
ConnectorConfig config = new ConnectorConfig();
config.setUsername("USERNAME");
config.setPassword("PASSWORD+TOKEN");
config.setCompression(true);
config.setTraceFile("traceLogs.txt");
config.setTraceMessage(true);
config.setPrettyPrintXml(true);
config.setAuthEndpoint("https://login.salesforce.com/services/Soap/u/39.0");
PartnerConnection connection = new PartnerConnection(config);
String soapEndpoint = config.getServiceEndpoint();
String apiVersion = "39.0";
String restEndpoint = soapEndpoint.substring(0, soapEndpoint.indexOf("Soap/")) + "async/" + apiVersion;
config.setRestEndpoint(restEndpoint);
bulkConnection = new BulkConnection(config);
Above code is working fine.
But in my case, I can't able to collect username & password for each of the customer's salesforce account.
Is this possible to create BulkConnection using accestoken?..
Please give me your suggestion.
Thanks,
Harish

Yahoo Oauth inconsistent "Invalid Signature"

H!I am having a very hard time with Yahoo Oauth right now.
So here's the problem, I am using scribe 3.1.5 and followed Yahoo's documentations(apparently they use Oauth1.0), I've been able to get the request token, then trade for the access token with the verifier. The problem emerges when I try to get user's GUID from URL http://social.yahooapis.com/v1/me/guid?format=json with the access token.
now, what's interesting is that, yahoo would sometimes give me the GUID back, and sometimes give me a "invalid signature" error. Sometimes I get 5 invalid signatures in a row, sometimes I get 15 successful calls in a row, most of the time it is like 40% invalid signatures and 60% success. What is even weirder is that sometimes I get a success when fetching GUID, but when i try to fetch user's profile IMMEDIATELY after the success with the identical access token and GUID, it gives me an invalid sigature...(wtf)
so here's the code I use:
Redirecting User:
Token requestToken = yahooService.getRequestToken();
getSession().setAttribute("yahooRequestToken", requestToken);
String authenticationUrl = yahooService.getAuthorizationUrl(requestToken);
redirect(authenticationUrl);
Getting callback:
#GET #Path("/oauthcallback/yahoo")
public Response yahooCallback(#QueryParam("oauth_token") String oAuthToken, #QueryParam("oauth_verifier") String oAuthVerifier) {
Token requestToken = (Token)getSession().getAttribute("yahooRequestToken");
Token accessToken = yahooService.getAccessToken(requestToken, oAuthVerifier);
UserProfile user = userService.findUserById(getUserId());
try{
//TODO occasioanlly yahoo returns invalid_signature, this is inconsistent and I have no idea why
String guid = yahooService.getGuid(accessToken);
String email = yahooService.getUserEmail(guid, accessToken);
.....
YahooService::Getting Access Token:
[the service object is protected final OAuthService service; in parent class]
#Override
public Token getAccessToken(Token requestToken, String oAuthVerifier) {
Verifier verifier = new Verifier(oAuthVerifier);
return service.getAccessToken(requestToken, verifier);
}
YahooService::Getting GUID:
#Override
public String getGuid(Token accessToken){
OAuthRequest requestA = new OAuthRequest(Verb.GET, GET_YAHOO);
service.signRequest(accessToken, requestA);
Response responseA = requestA.send();
JsonParser parser = new JsonParser();
//sometimes the response body is a invalid signature error message
JsonObject json = (JsonObject)parser.parse(responseA.getBody());
return json.getAsJsonObject("guid").get("value").getAsString();
}
YahooService::Getting User Email:
#Override
public String getUserEmail(String guid, Token accessToken) {
String profileCallUrl = GET_YAHOO_PROFILE.replaceAll("GUID", guid);
OAuthRequest requestB = new OAuthRequest(Verb.GET, profileCallUrl);
service.signRequest(accessToken, requestB);
requestB.addHeader("realm", "yahooapis.com");
Response responseB = requestB.send();
JsonParser parser = new JsonParser();
//sometimes the response body is a invalid signature error message
JsonObject jsonProfile = (JsonObject)parser.parse(responseB.getBody());
...processing code, error free
}
I know YahooAPI class in Scribe 3.1.5 in maven distribution is like 2 years old, but I doubt it would lead to such inconsistent behavior. Scribe's built in support for Google and Live oauth is basically useless, unfortunately, unlike Google or Hotmail which both have awesome doc so that I could basically figure out everything myself, Yahoo's doc stops at getting the access token, I can not find useful explanation on why I would get an invalid signature SOMETIMES with my access token
Please help! Thanks in advance
Its looks like Yahoo issue, I have same error message since few days :
http://developer.yahoo.com/forum/OAuth-General-Discussion-YDN-SDKs/signature-invalid-when-making-calls-to-the/1385735171123-8a38d8cf-815b-43ac-9d77-5bd2f2f60796
There is no need to ask for GUID to yahoo as yahoo returns GUID of the currently logged in user at the time of giving you the access token so if you have a access token you also have a GUID in the response.
Refer this

Categories