prevent redirect on result - java

Is it possible to prevent or stop the redirect in the answer retrieved from an OAuthRequest.send()? Would I use OAuthRequest.addHeader(), and if so, what key and value should I use?
Here is the google groups answer to the question for the problem that I'm having: answer.
Thanks
final OAuthService service =
new ServiceBuilder().provider(TumblrApi.class)
.apiKey(Tumblr.CONSUMER_KEY).apiSecret(Tumblr.CONSUMER_SECRET)
.debug().build();
// Step 5
final OAuthRequest request = new OAuthRequest(Verb.GET, methodUrl);
request.addQuerystringParameter("api_key", Tumblr.CONSUMER_KEY);
service.signRequest(accessToken, request); // the access token from step 4
final Response response = request.send();

Related

How to set OAuth realm in RestAssured

I am using RestAssured library for automating NetSuite Restlets. This Restlets are using OAuth 1.0 for authentication. Apart from consumer key, consumer secret, access token and token secret, I need to set advanced fields like REALM. But I couldn't find any way to set that in RestAssured.
RequestSpecification request = new RequestSpecBuilder()
.addHeader("Content-Type", ContentType.JSON.toString())
.setBaseUri(url).build()
.auth().oauth(
netsuiteConfig.getNetsuiteConsumerKey(),
netsuiteConfig.getNetsuiteConsumerSecret(),
netsuiteConfig.getNetsuiteTokenId(),
netsuiteConfig.getNetsuiteTokenSecret()
);
Here is the api call using Postman
RestAssured does not support this. Create OAuth 1.0 string using some library (I have used com.github.seratch:signedrequest4j) and set Authorization header in RestAssured RequestSpecification.
OAuthConsumer consumer = new OAuthConsumer(consumerKey, consumerSecret);
OAuthAccessToken accessToken = new OAuthAccessToken(tokenId, tokenSecret);
OAuthRealm realm = new OAuthRealm(myRealm);
SignedRequest request =
SignedRequestFactory.create(realm, consumer, accessToken);
request.readQueryStringAndAddToSignatureBaseString(url);
request.setHeader("Content-Type", "application/json");
String oAuthNonce = String.valueOf((new SecureRandom()).nextLong());
Long oAuthTimestamp = System.currentTimeMillis() / 1000L;
String signature = request.getSignature(url,
HttpMethod.POST, oAuthNonce, oAuthTimestamp);
String authorizationHeader = request
.getAuthorizationHeader(signature, oAuthNonce, oAuthTimestamp);
I was using the library mentioned in the previous answer but then I realised I needed to use PATCH requests which wasn't supported.
I started using the google oauth client instead and after days of trying, finally got this example working:
val signer = OAuthHmacSigner()
signer.clientSharedSecret = CONSUMER_SECRET
signer.tokenSharedSecret = TOKEN_SECRET
val oauthParameters = OAuthParameters()
oauthParameters.consumerKey = CONSUMER_KEY
oauthParameters.token = ACCESS_TOKEN
oauthParameters.signer = signer
val genericUrl = GenericUrl("https://{ACC_ID}.suitetalk.api.netsuite.com/path/to/endpoint")
oauthParameters.version = "1.0"
oauthParameters.computeNonce()
oauthParameters.computeTimestamp()
oauthParameters.computeSignature("GET", genericUrl)
oauthParameters.realm = REALM
val authHeader = oauthParameters.authorizationHeader
RestAssured.with()
.log().all()
.header("Authorization", authHeader)
.urlEncodingEnabled(false)
.request(Method.GET, genericUrl.toString())
.then()
.statusCode(200)
urlEncoding is set to false for urls with query params that are already encoded. For example:
{url}/invoice?q=internalid%20IS%2012
I hope it helps someone in the future!

Spring Boot TestRestTemplate: Pass along session id

I've got a Spring Boot application with some tests. The application's 'happy-path' requires that the user send a request to start a session, then it can make other requests to other services.
I'm trying to test these other services, but I need a session started first. My mindset was as follows:
Hit the session start endpoint
Get the session cookie from that request
Slap that cookie onto future requests made during testing.
To achieve that, I've got this mess:
String s = t.postForEntity(loginUrl, remoteSessionPacket, String.class)
.getHeaders()
.get("Set-Cookie").get(0);
String[] split = s.split(";");
String sessionId = "";
for (String s1 : split) {
if(s1.contains("SESSION"))
{
sessionId = s1;
}
}
HttpHeaders headers = new HttpHeaders();
headers.add("SESSION", sessionId);
HttpEntity<?> httpEntity = new HttpEntity<>(headers);
RemoteDTOPacket= new RemoteDTOPacket();
packet.Token = UUID.randomUUID().toString();
String url = "http://localhost:" + port + "/domain/SomeFunction";
ResponseEntity<ResponsePacket> response = t.postForEntity(url, packet, ResponsePacket.class, httpEntity);
Assert.assertEquals(0, (long) response.getBody().count);
Obviously, this doesn't work and errors are thrown with abandon.
Does anyone know how to accomplish what I'm trying to do?
Any help is greatly appreciated.
Session id is stored in cookie that is stored in "Cookie" header - not in separate request header. Something like this should work:
List<String> coockies = t.postForEntity(loginUrl, remoteSessionPacket, String.class)
.getHeaders()
.get("Set-Cookie");
HttpHeaders requestHeaders = new HttpHeaders();
requestHeaders.put(HttpHeaders.COOKIE, coockies);
HttpEntity<Void> requestEntity = new HttpEntity<>(requestHeaders);
Or you can get exact session id cookie that will be most probably stored under "JSESSIONID" key.

Google OAuth Java client and Twitter API

I'm having issues invoking twitter REST API using Google OAuth Java Client. I'm able to do the first steps correctly:
Set the authorization URL,
Get the temporary token,
Generate the final token.
Then the OAuth Javadoc says:
Use the stored access token to authorize HTTP requests to protected
resources by setting the OAuthParameters.token and using
OAuthParameters as the HttpRequestInitializer.
It's in this step that I have issues. First of all if I only set the OAuthParameters.token value I'll get a null exception because the signer isn't set so what I presently have is:
OAuthHmacSigner signer = new OAuthHmacSigner();
signer.clientSharedSecret=TWITTER_CONSUMER_SECRET;
String oauthToken = req.getParameter("oauth_token");
String oauthVerifier = req.getParameter("oauth_verifier");
OAuthGetAccessToken accessTokenRequest = new OAuthGetAccessToken(TWITTER_ACESS_TOKEN_URL);
accessTokenRequest.consumerKey=TWITTER_CONSUMER_KEY;
accessTokenRequest.signer=signer;
accessTokenRequest.transport=HTTP_TRANSPORT;
accessTokenRequest.temporaryToken=oauthToken;
accessTokenRequest.verifier=oauthVerifier;
OAuthCredentialsResponse credentials = accessTokenRequest.execute();
String token = credentials.token;
OAuthParameters params = new OAuthParameters();
params.token=token;
params.version="1.0";
params.consumerKey=TWITTER_CONSUMER_KEY;
params.signer=signer;
HttpRequestFactory requestFactory = HTTP_TRANSPORT.createRequestFactory(params);
HttpResponse twResponse = requestFactory.buildGetRequest(new GenericUrl("https://api.twitter.com/1.1/account/verify_credentials.json")).execute();
The result is always:
WARNING: Authentication error: Unable to respond to any of these
challenges: {} com.google.api.client.http.HttpResponseException: 401
OK {"errors":[{"message":"Could not authenticate you","code":32}]}
If I try the Authorization header given by Twitter OAuth tool through a REST Chrome extension tool it works perfectly so it's not an account issue. When I change it for the Authorization header value computed by the Google OAuth Java client library it doesn't work.
I don't get what I'm doing wrong.
Solution: Follow the tutorial in the link provided by #Arkanon, I missed refreshing the signer token secrete through:
signer.tokenSharedSecret
I just modified the code on this page about using google-oauth-java-client to send a request to Twitter and it worked fine once I replaced the relevant block with this:
while (currentLine.equalsIgnoreCase("n")) {
System.out.println("Enter the verification PIN provided by Twitter:");
currentLine = in.readLine();
}
and then added the following to the accessToken object:
accessToken.verifier = currentLine;
Once the PIN provided by the Twitter site is typed into the Java console and you hit Enter, the process completes and the protected resource can be accessed and the desired JSON response is received.
The only other changes I made to that code were to provide the Twitter constants as follows:
private static final String CONSUMER_KEY =
"enter-your-consumer-key-here";
private static final String CONSUMER_SECRET =
"enter-your-consumer-secret-here";
private static final String PROTECTED_SERVICE_URL =
"https://api.twitter.com/1.1/statuses/home_timeline.json";
private static final String REQUEST_TOKEN_URL =
"https://api.twitter.com/oauth/request_token";
private static final String AUTHORIZE_URL =
"https://api.twitter.com/oauth/authenticate";
private static final String ACCESS_TOKEN_URL =
"https://api.twitter.com/oauth/access_token";
Maybe this is not the exact same process you're hoping to achieve, but hopefully the code on that page will help you to spot anything you might have misunderstood. (And I agree that the documentation for the Google libraries is not all it could be.)

Google API Java GET request with body content

My Goal is to request GoogleTaskAPI for TASKLIST with specified no.of result.
It works fine, If I m passing no requestBody. But I need to pass request parameter to specific number of results to be returned. When I do that, it creates new Tasklist, Instead of listing. So how to do this?
My Code:
GoogleAccessProtectedResource access = new GoogleAccessProtectedResource(accessToken, httpTransport, jsonFactory, clientId, clientSecret, refreshToken);
HttpRequestFactory rf = httpTransport.createRequestFactory(access);
String endPointUrl = "https://www.googleapis.com/tasks/v1/users/#me/lists";
String requestBody = "{\"maxResults\":3}";
GenericUrl endPoint = new GenericUrl(endPointUrl);
ByteArrayContent content = new ByteArrayContent("application/json", requestBody.getBytes());
//Try 0: Works, But Retrieving all of my Tasklist, I need only 3
//HttpRequest request = rf.buildGetRequest(endPoint);
//-------
//Try 1: Fails to retrieve
//HttpRequest request = rf.buildGetRequest(endPoint);
//request.setContent(content);
//request.getContent().writeTo(System.out);
//-------
//Try 2: Fails to retrieve
HttpRequest request = rf.buildRequest(HttpMethod.GET, endPoint, content);
request.getContent().writeTo(System.out);
//-------
HttpResponse response = request.execute();
String str = response.parseAsString();
utils.log(str);
maxResults is a query parameter, not a request parameter, so you can just put it in the url:
String endPointUrl = "https://www.googleapis.com/tasks/v1/users/#me/lists?maxResults=3";
You should also consider using the Java client's Tasks interface for making requests; it may be a little easier since it handles the details of the url for you:
http://code.google.com/p/google-api-java-client/wiki/APIs#Tasks_API

Twitter API status update always returns "Incorrect signature"

I'm using Signpost as OAuth implementation for posting to Twitter. And implemented the GoogleAppEngineOAuthConsumer and GoogleAppEngineOAuthProvider classes, but since they're pretty trivial, so I'm not providing their sources here (yet).
Here's my authentication part, which seems to work just fine.
LoginServlet.java:
// fetching the request token
OAuthConsumer consumer = new GoogleAppEngineOAuthConsumer(CONSUMER_KEY, CONSUMER_SECRET);
OAuthProvider provider = new GoogleAppEngineOAuthProvider(REQUEST_TOKEN_URL, ACCESS_TOKEN_URL, AUTHORIZATION_URL);
String redirectUrl = provider.retrieveRequestToken(consumer, CALLBACK_URL);
// cache the request token and request token secret
response.sendRedirect(redirectUrl);
CallbackServlet.java
// fetching the access token
String verifier = (String) req.getParameter("oauth_verifier");
// retrieve request token and request token secret from cache
OAuthConsumer consumer = new GoogleAppEngineOAuthConsumer(CONSUMER_KEY, CONSUMER_SECRET);
OAuthProvider provider = new GoogleAppEngineOAuthProvider(REQUEST_TOKEN_URL,
consumer.setTokenWithSecret(token, tokenSecret);
provider.setOAuth10a(true);
provider.retrieveAccessToken(consumer, verifier);
// store access token and access token secret
And here's the actual problematic part.
TweetServlet.java
OAuthConsumer consumer = new GoogleAppEngineOAuthConsumer(CONSUMER_KEY, CONSUMER_SECRET);
// retrieve access token and access token secret from storage
consumer.setTokenWithSecret(accessToken, accessTokenSecret);
final HTTPRequest updateStatus = new HTTPRequest(new URL("http://api.twitter.com/1/statuses/update.json"), HTTPMethod.POST);
updateStatus.setPayload(("status=" + URLEncoder.encode(message, "UTF-8")).getBytes());
consumer.sign(updateStatus);
logger.debug(new String(URLFetchServiceFactory.getURLFetchService().fetch(updateStatus).getContent()));
Each and every time it results: {"request":"/1/statuses/update.json","error":"Incorrect signature"}.
I was able to solve this by myself. The problem was that I wasn't setting a Content-Type header to the request, so the signing didn't sign the parameters and it resulted the invalid signature. Once I set it to application/x-www-form-urlencoded it started working.
final HTTPRequest updateStatus = new HTTPRequest(new URL("http://api.twitter.com/1/statuses/update.json"), HTTPMethod.POST);
updateStatus.addHeader(new HTTPHeader("Content-Type", "application/x-www-form-urlencoded"));

Categories

Resources