Twitter4j: java.lang.IllegalStateException: Access token already available - java

I am using Twitter4j for creating Twitter client with JSP and servets. When I am requesting for access token I am getting the following exception:
java.lang.IllegalStateException: Access token already available.
Then I searched on Stack Overflow. I got this post where in solution the author has written:
I was setting an Access Token hard coded by the Configuration Builder.
But they haven't mentioned how they fixed it.I am also not hardcoding access token. Here is my code
StringBuffer callbackURL = request.getRequestURL();
System.out.println("callbackurl is" + callbackURL);
int index = callbackURL.lastIndexOf("/");
callbackURL.replace(index, callbackURL.length(), "").append("/callback");
ConfigurationBuilder cb = new ConfigurationBuilder();
cb.setDebugEnabled(true)
.setOAuthConsumerKey(getServletContext().getInitParameter("consumerKey"))
.setOAuthConsumerSecret(getServletContext().getInitParameter("consumerSecret"));
TwitterFactory tf = new TwitterFactory(cb.build());
Twitter twitter = tf.getInstance();
System.out.println("Twitter is" + twitter);
request.getSession().setAttribute("twitter", twitter);
RequestToken requestToken = twitter.getOAuthRequestToken(callbackURL.toString());
System.out.println("request token is " + requestToken);
request.getSession().setAttribute("requestToken", requestToken);
System.out.println(requestToken.getAuthenticationURL());
response.sendRedirect(requestToken.getAuthenticationURL());
This is the stacktrace
HTTP ERROR 500
Problem accessing /Demo1. Reason:
Access token already available.
Caused by:
java.lang.IllegalStateException: Access token already available.
at twitter4j.auth.OAuthAuthorization.getOAuthRequestToken(OAuthAuthorization.java:113)
at twitter4j.auth.OAuthAuthorization.getOAuthRequestToken(OAuthAuthorization.java:104)
at twitter4j.TwitterBaseImpl.getOAuthRequestToken(TwitterBaseImpl.java:281)
at com.example.Demo1.doGet(Demo1.java:69)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:707)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:820)
at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:565)
at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:479)
at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:119)
at org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:521)
at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:227)
at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1031)
at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:406)
at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:186)
at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:965)
at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:117)
at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:111)
at org.eclipse.jetty.server.Server.handle(Server.java:349)
at org.eclipse.jetty.server.AbstractHttpConnection.handleRequest(AbstractHttpConnection.java:449)
at org.eclipse.jetty.server.AbstractHttpConnection$RequestHandler.headerComplete(AbstractHttpConnection.java:910)
at org.eclipse.jetty.http.HttpParser.parseNext(HttpParser.java:634)
at org.eclipse.jetty.http.HttpParser.parseAvailable(HttpParser.java:230)
at org.eclipse.jetty.server.AsyncHttpConnection.handle(AsyncHttpConnection.java:76)
at org.eclipse.jetty.io.nio.SelectChannelEndPoint.handle(SelectChannelEndPoint.java:609)
at org.eclipse.jetty.io.nio.SelectChannelEndPoint$1.run(SelectChannelEndPoint.java:45)
at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:599)
at org.eclipse.jetty.util.thread.QueuedThreadPool$3.run(QueuedThreadPool.java:534)
at java.lang.Thread.run(Thread.java:679)

I met similar problem recently and I debug the source code line by line. I finally found that the configuration would take multiple sources before its ready. When setting the properties such as consumerKey, consumerSecret, it would set from these lines
ConfigurationBuilder cb = new ConfigurationBuilder();
cb.setDebugEnabled(true)
.setOAuthConsumerKey(getServletContext().getInitParameter("consumerKey"))
.setOAuthConsumerSecret(getServletContext().getInitParameter("consumerSecret"));
In addition, twitter4j will scan the classpath and find the property files which defines the related key value pairs. I created this file by following the instruction of the tutorial and I forget to delete this. But in the tutorial, it just told you how to get to access the api with the generated accessToken and accessSecret, which were the cause of the IllegalStatusException.
After I found this issue, and I deleted the accessToken and accessTokenSecret keys in the property file. Then problem solved.
Hope this can help you.

I have faced same problem, that is because the access token is already available in the configuration builder. so you need to set it as null in configuration builder
StringBuffer callbackURL = request.getRequestURL();
System.out.println("callbackurl is" + callbackURL);
int index = callbackURL.lastIndexOf("/");
callbackURL.replace(index, callbackURL.length(), "").append("/callback");
ConfigurationBuilder cb = new ConfigurationBuilder();
cb.setDebugEnabled(true).setOAuthConsumerKey((String) "consumerkey")
.setOAuthConsumerSecret("consumersecret").setOAuthAccessToken(null)
.setOAuthAccessTokenSecret(null)
.setOAuthRequestTokenURL("https://api.twitter.com/oauth/request_token")
.setOAuthAuthorizationURL("https://api.twitter.com/oauth/authorize")
.setOAuthAccessTokenURL("https://api.twitter.com/oauth/access_token");
TwitterFactory tf = new TwitterFactory(cb.build());
Twitter twitter = tf.getInstance();
System.out.println("Twitter is" + twitter);
request.getSession().setAttribute("twitter", twitter);
RequestToken requestToken = twitter.getOAuthRequestToken(callbackURL.toString());
System.out.println("request token is " + requestToken);
request.getSession().setAttribute("requestToken", requestToken);
System.out.println(requestToken.getAuthenticationURL());
response.sendRedirect(requestToken.getAuthenticationURL());
with this code am able to run the program properly.

Related

Facebook4J OAuth failing

I am trying to search for public items using Facebook4J, I understad I need an appId AND appSecret which I have, the app token is the these two with a pipe symbol between them (as I understand). I can not understand why I am gett an OAuthError , Please see my code below and precise error code.
facebook4j.conf.ConfigurationBuilder fac = new facebook4j.conf.ConfigurationBuilder();
fac.setDebugEnabled(true)
.setOAuthAppId("appId")
.setOAuthAppSecret("appSecret")
.setOAuthPermissions("email,publish_stream");
fac.setOAuthAccessToken(accessToken);
FacebookFactory ff = new FacebookFactory(fac.build());
Facebook facebook = ff.getInstance();
ResponseList<JSONObject> results = facebook.search("%whatever");
This is the following error code I get. Error code one seems to be unknown API???
Exception in thread "main" message - An unknown error has occurred.
code - 1
Relevant information for error recovery can be found on the Facebook Developers Document:
https://developers.facebook.com/docs/graph-api/using-graph-api/#errors
FacebookException{statusCode=500, errorType='OAuthException', errorMessage='An unknown error has occurred.', errorCode=1, errorSubcode=-1, version=2.4.2}
at facebook4j.internal.http.HttpClientImpl.request(HttpClientImpl.java:179)
at facebook4j.internal.http.HttpClientWrapper.request(HttpClientWrapper.java:61)
at facebook4j.internal.http.HttpClientWrapper.get(HttpClientWrapper.java:89)
at facebook4j.FacebookImpl.get(FacebookImpl.java:2742)
at facebook4j.FacebookImpl.search(FacebookImpl.java:2337)
at facebook4j.FacebookImpl.search(FacebookImpl.java:2332)
at Main.facebook4JRequest(Main.java:37)
at Main.main(Main.java:15)
Try using the below code it worked for me.
Facebook facebook = new FacebookFactory().getInstance();
facebook.setOAuthAppId("XXXXXX", "XXXXXXXXXXXX");
String accessTokenString = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX";
AccessToken at = new AccessToken(accessTokenString);
facebook.setOAuthAccessToken(at);
ResponseList<Post> feeds = facebook.getPosts("%whatever", new Reading().limit(80));

How to implement application-only authentication for twitter in Grails using scribe?

Earlier i was using GET search/tweets of Twitter API 1.0 To get tweets according to #tags in Grails
Map jsonMap = grails.converters.JSON.parse(new URL('http://search.twitter.com/search.json?q=%23' + URLEncoder.encode(tag) + '&offset=' + offset + 'result_type=mixed&lang=en&page=' + page).text)
But due to change in Twitter API version 1.1 now the above call requires Authentication.
I want to fetch tweets on behalf of Application(Authentication) not by user Authentication.
Is this possible?
I came across application-only-auth but unable to implement it.
https://dev.twitter.com/docs/auth/application-only-auth
How to implement above using scribe API in Grails.
I have done like this and it worked for me.
OAuthService service = new ServiceBuilder().provider(TwitterApi.class).apiKey(grailsApplication.config.oauth.providers.twitter.key).apiSecret(grailsApplication.config.oauth.providers.twitter.secret).build()
OAuthRequest request = new OAuthRequest(Verb.GET, 'https://api.twitter.com/1.1/search/tweets.json?q=%23' + URLEncoder.encode(tag) + '&count=100&result_type=mixed&lang=en');
Token accessToken = new Token(grailsApplication.config.oauth.providers.twitter.accessToken, grailsApplication.config.oauth.providers.twitter.accessSecret)
service.signRequest(accessToken, request);
Response response = request.send();
JSONElement jsonMap = grails.converters.JSON.parse(response.getBody());

OAuth Vimeo with Scribe "Invalid API Key" (Error Code 100)

I'm trying to authenticate in Vimeo using Scribe. It's not going over too well. I keep getting error code 100 back, but it still gives me an Authorization URL and when I go to it I'm able to grant access. It's just when I enter the authorization code in and try to trade the request token for an access token it doesn't work. I'm using the Facebook example and tweaking it to work with Vimeo. I don't really know what I'm doing here. I asked a question earlier and was told that I need to include apache commons codec on my classpath. Well, I included it in my environment variables and that didn't change anything. So I just added it to my libraries for the project and that seemed to get me a step farther. Now I just have no idea what to do from here. I don't understand why I'm getting this. Here's my code and output:
public class VimeoTest
{
private static final String NETWORK_NAME = "Vimeo";
private static final Token EMPTY_TOKEN = null;
public static void main(String[] args)
{
// Replace these with your own api key and secret
String apiKey = "MYAPIKEY";
String apiSecret = "MYAPISECRET";
OAuthService service = new ServiceBuilder()
.provider(VimeoApi.class)
.apiKey(apiKey)
.apiSecret(apiSecret)
.debug()
.build();
Scanner in = new Scanner(System.in);
System.out.println("=== " + NETWORK_NAME + "'s OAuth Workflow ===");
System.out.println();
OAuthRequest orequest = new OAuthRequest(Verb.GET, "http://vimeo.com/api/rest/v2");
orequest.addQuerystringParameter("method", "vimeo.test.null");
Response send = orequest.send();
System.out.println(send.getBody());
// Obtain the Authorization URL
System.out.println("Fetching the Authorization URL...");
Token requestToken = service.getRequestToken();
String authorizationUrl = service.getAuthorizationUrl(requestToken);
System.out.println("Got the Authorization URL!");
System.out.println("Now go and authorize Scribe here:");
//I do NOT want to have to do this. Is there any other way I can have this authorize without going to a web browser to do this?
System.out.println(authorizationUrl);
System.out.println("And paste the authorization code here");
System.out.print(">>");
Verifier verifier = new Verifier(in.nextLine());
System.out.println();
// Trade the Request Token and Verfier for the Access Token
System.out.println("Trading the Request Token for an Access Token...");
Token accessToken = service.getAccessToken(EMPTY_TOKEN, verifier);
//****Breaks on the line above.****
//I think it's because the orequest.send() returned a 100 error code
//Note, EMPTY_TOKEN is declared as null, but I think that's ok. Verifier is not null.
System.out.println("Got the Access Token!");
System.out.println("(if your curious it looks like this: " + accessToken + " )");
System.out.println();
Here's the output:
=== Vimeo's OAuth Workflow ===
1.0
<?xml version="1.0" encoding="utf-8"?>
<rsp generated_in="0.0033" stat="fail">
<err code="100" expl="The API key passed was not valid" msg="Invalid API Key" />
</rsp>
Fetching the Authorization URL...
obtaining request token from http://vimeo.com/oauth/request_token
setting oauth_callback to oob
generating signature...
base string is: POST&http%3A%2F%2Fvimeo.com%2Foauth%2Frequest_token&oauth_callback%3Doob%26oauth_consumer_key%3DACONSUMERKEY%26oauth_nonce%3D2861480766%26oauth_signature_method%3DHMAC-SHA1%26oauth_timestamp%3D1331941401%26oauth_version%3D1.0
signature is: 7H/C4F4rK0FYZ5oZGf76Rl8P8yQ=
appended additional OAuth parameters: { oauth_callback -> oob , oauth_signature -> 7H/C4F4rK0FYZ5oZGf76Rl8P8yQ= , oauth_version -> 1.0 , oauth_nonce -> 2861480766 , oauth_signature_method -> HMAC-SHA1 , oauth_consumer_key -> ACONSUMERKEY , oauth_timestamp -> 1331941401 }
using Http Header signature
sending request...
response status code: 200
response body: oauth_token=bf3da4ec799559c9f8b1f8bda2b8d6ee&oauth_token_secret=AOAUTHTOEKN SECRET&oauth_callback_confirmed=true
Got the Authorization URL!
Now go and authorize Scribe here:
http://vimeo.com/oauth/authorize?oauth_token=bf3da4ec799559c9f8b1f8bda2b8d6ee
And paste the authorization code here
>>unicorn-duqx0
Exception in thread "main" java.lang.NullPointerException
Trading the Request Token for an Access Token...
obtaining access token from http://vimeo.com/oauth/access_token
at org.scribe.oauth.OAuth10aServiceImpl.getAccessToken(OAuth10aServiceImpl.java:75)
at autouploadermodel.VimeoTest.main(VimeoTest.java:51)
Java Result: 1
BUILD SUCCESSFUL (total time: 27 seconds)
Edit: added .debug() to new ServiceBuilder() and updated the output accordingly.
Change this line:
Token accessToken = service.getAccessToken(EMPTY_TOKEN, verifier);
For:
Token accessToken = service.getAccessToken(requestToken, verifier);
Edit
The whole key unauthorized part is because this piece of code:
OAuthRequest orequest = new OAuthRequest(Verb.GET, "http://vimeo.com/api/rest/v2");
orequest.addQuerystringParameter("method", "vimeo.test.null");
Response send = orequest.send();
System.out.println(send.getBody());
You're trying to make a GET request to the api root (not sure even if this is a valid resource) without signing it. Of course it's going to yield an unauthorized error.

unable to updated/deleted/retrieve Calendar Events using GAE Java API with two legged authentication

Hi I am writing a connector tool using GAE Java which adds,updates, deletes and
retrieves calendar events.I am using 2 legged authentication for the same. I am able to add new events successfully using 2 legged authentication but not able to
update, delete or retrieve events using the same.
It gives following error while I try to do either of update/delete/retrieve operation on calendar event.
com.google.gdata.util.AuthenticationException: OK
<HTML>
<HEAD>
<TITLE>Token invalid - Invalid AuthSub token.</TITLE>
</HEAD>
<BODY BGCOLOR="#FFFFFF" TEXT="#000000">
<H1>Token invalid - Invalid AuthSub token.</H1>
<H2>Error 401</H2>
</BODY>
</HTML>
The same code works fine if I remove OAuth specific code and just use service.setUserCredentials() method.
Kindly help me out to resolve this issue. Please revert back in case
more information on this is required.
Thanks in advance.
-Nirzari
Below is the code snippet
//Code for getCalendarEvents
String url = FEED_URL + "?xoauth_requestor_id="
+ "u...#domain.com";
URL postUrl = new URL(url);
GoogleOAuthParameters oauthParameters = new GoogleOAuthParameters();
oauthParameters.setScope(Scope);
oauthParameters.setOAuthConsumerKey(ConsumerKey);
oauthParameters.setOAuthConsumerSecret(secret);
CalendarService myService = new CalendarService("getAppointments");
OAuthSigner signer = new OAuthHmacSha1Signer();
myService.setOAuthCredentials(oauthParameters, signer);
CalendarQuery myQuery = new CalendarQuery(postUrl);
CustomParameter customParameter = new CustomParameter("showdeleted",
"true");
myQuery.addCustomParameter(customParameter);
CalendarEventFeed resultFeed = myService.query(myQuery,
CalendarEventFeed.class);
//Code for Update Appointment
String url = FEED_URL + "?xoauth_requestor_id=" +
"usern...#domain.com";
URL postUrl = new URL(url);
GoogleOAuthParameters oauthParameters = new GoogleOAuthParameters();
oauthParameters.setScope(Scope);
oauthParameters.setOAuthConsumerKey(ConsumerKey);
oauthParameters.setOAuthConsumerSecret(secret);
CalendarService myService = new CalendarService("updateAppointment");
OAuthSigner signer = new OAuthHmacSha1Signer();
myService.setOAuthCredentials(oauthParameters, signer);
CalendarQuery myQuery = new CalendarQuery(postUrl);
myQuery.setExtendedPropertyQuery(new ExtendedPropertyMatch(
"Prop_Name", value));
CalendarEventFeed resultFeed = myService.getFeed(myQuery,
CalendarEventFeed.class);
if (resultFeed != null && resultFeed.getEntries().size() > 0) {
CalendarEventEntry matchEntry = (CalendarEventEntry) resultFeed
.getEntries().get(0);
updateCalendarEntry(matchEntry, description, title, start, end, startTime, endTime, location, priavte, guestList);
matchEntry.update();
One of the possible causes could be that user email is not URL encoded (# should be encoded as %40). Use this code, that handles URL encoding automatically:
query.addCustomParameter(new CustomParameter("xoauth_requestor_id", userEmail));
rather than append parameter manually.
Another possible cause is that your app doesn't have granted access to Calendar by administrator of Google Apps domain, to which the user belongs. You can check it on this page: https://www.google.com/a/cpanel/DOMAIN-NAME/ManageOauthClients.

Google Calendar API and OAuth problem

I get the error
com.google.gdata.util.AuthenticationException: Unknown authorization header
at com.google.gdata.client.http.HttpGDataRequest.handleErrorResponse(HttpGDataRequest.java:600) ~[gdata-core-1.0.jar:na]
at com.google.gdata.client.http.GoogleGDataRequest.handleErrorResponse(GoogleGDataRequest.java:563) ~[gdata-core-1.0.jar:na]
at com.google.gdata.client.http.HttpGDataRequest.checkResponse(HttpGDataRequest.java:552) ~[gdata-core-1.0.jar:na]
at com.google.gdata.client.http.HttpGDataRequest.execute(HttpGDataRequest.java:530) ~[gdata-core-1.0.jar:na]
at com.google.gdata.client.http.GoogleGDataRequest.execute(GoogleGDataRequest.java:535) ~[gdata-core-1.0.jar:na]
when trying to access the Google Calendar data via their API.
Here is what happens before that error.
1) I authenticate with Google:
final AccessTokenResponse response =
new GoogleAuthorizationCodeGrant(httpTransport,
jsonFactory,
clientId, clientSecret, authorizationCode,
redirectUrl).execute();
final GoogleAccessProtectedResource accessProtectedResource =
new GoogleAccessProtectedResource(
response.accessToken, httpTransport, jsonFactory,
clientId, clientSecret,
response.refreshToken);
LOGGER.debug("response.accessToken: {}", response.accessToken);
this.oauthAccessToken = response.accessToken;
...
2) I read some data via the tasks API:
this.service =
new Tasks(httpTransport, accessProtectedResource,
jsonFactory);
this.service.setApplicationName(this.applicationName);
This seems to work.
3) Then I try to read data from the Google Calendar API:
final OAuthHmacSha1Signer signer = new OAuthHmacSha1Signer();
final GoogleOAuthParameters oauth = new GoogleOAuthParameters ();
oauth.setOAuthConsumerKey("myapp.com");
oauth.setOAuthConsumerSecret(CLIENT_SECRET); // Client secret from "Google API access" page, "Client secret" entry
oauth.setOAuthToken(this.oauthAccessToken); // Access token from step 1
oauth.setOAuthTokenSecret(aAuthorizationCode);
// aAuthorizationCode is taken from the callback URL.
// For http://myapp.com/oauth2callback?code=4/uy8Arb4bhRPwWYSr3QwKPt9lIZkt
// aAuthorizationCode is equal to "4/uy8Arb4bhRPwWYSr3QwKPt9lIZkt" (without quotes)
oauth.setScope(SCOPE_CALENDAR); // https://www.google.com/calendar/feeds/
final CalendarService calendarService =
new CalendarService(APPLICATION_NAME);
calendarService
.setOAuthCredentials(oauth, signer);
LOGGER.debug("calendarService: {}", calendarService);
final URL feedUrl =
new URL(
"http://www.google.com/calendar/feeds/default/allcalendars/full");
final CalendarFeed resultFeed =
calendarService.getFeed(feedUrl, CalendarFeed.class);
At the last line (calendarService.getFeed...) the aforementioned exception occurs.
I have following questions:
1) Is my call
oauth.setOAuthConsumerKey
correct?
I. e. is the "consumer key" equal to "Product name" in the Google API console, or to "Client ID" field (value is something like 42912397129473.apps.googleusercontent.com)
2) Is the setOAuthTokenSecret correct? I. e. is it the code that I get, when Google redirects the user back to my app?
3) If questions 2 and 3 were answered with yes, what else can be the cause of my problem?
Thanks
Dmitri
P. S.: Previously, I could access Google calendar with simple access (i. e. with Google user name and password). However, this is not an option now because users of my app will not want to give away their Google password.
Finally, I solved my problem by following the example at
http://code.google.com/p/gdata-java-client/source/browse/trunk/java/sample/oauth/OAuthExample.java
My advice to all future victims^W users of OAuth: Pay attention to the smallest details in the OAuth tutorials. The OAuth devil lies in details.

Categories

Resources