I am trying to use Java Jersey instead of Google client libraries to access the Google File API, but I keep getting returned a response status of "401 Unauthorized". Prior to invoking the call, I have obtained an access token from Google, using Oauth:
public static String getGoogleFileResource(final String fileId,
final String accessToken) {
//projection
ClientConfig cc = new DefaultClientConfig();
cc.getProperties().put(ClientConfig.PROPERTY_FOLLOW_REDIRECTS, true);
Client client = Client.create(cc);
String url = String
.format("https://www.googleapis.com/drive/v2/files/%s?fields=downloadUrl&key=%s",
fileId, GoogleClientConstants.GOOGLE_api_key);
WebResource webResource = client.resource(url);
String response = webResource
.accept(MediaType.APPLICATION_JSON_TYPE,
MediaType.APPLICATION_XML_TYPE)
.header("Authorization", "Bearer " + accessToken)
.get(String.class);
logger.info("Authorization - " + "Bearer " + accessToken);
logger.info(" reponse " + response);
return response;
}
What am I doing wrong ?
Turns out you need to add your access token to the http request header.
In the Google developer's guide: "uploading a file"
https://developers.google.com/drive/manage-uploads
You need to send a post request like this:
POST /upload/drive/v2/files?uploadType=media HTTP/1.1
Host: www.googleapis.com
Content-Type: image/jpeg
Content-Length: number_of_bytes_in_JPEG_file
Authorization: your_auth_token
JPEG data
note that in the header you need to put a your_auth_token
Related
First I wanted to authenticate my java application using OkHttp and then after authentication the response returns a session ID(key) that I wanted to use in subsequent API calls. below is the code that I am using to achieve this.
String url = "my application url";
String username = "xxx";
String password = "zzz";
String userpass = username + ":" + password;
String basicAuth = "Basic :" + new String(Base64.getEncoder().encode(userpass.getBytes()));
OkHttpClient client = new OkHttpClient();
Response response ;
Request request = new Request.Builder()
.url(url)
.addHeader("Authorization", basicAuth)
.build();
response = client.newCall(request).execute();
if (!response.isSuccessful()) throw new IOException("Unexpected code " + response);
System.out.println(response.body().string());
but its throwing an error saying
{"responseStatus":"FAILURE","responseMessage":"Request method 'GET' not supported","errorCodes":null,"errors":[{"type":"METHOD_NOT_SUPPORTED","message":"Request method 'GET' not supported"}],"errorType":"GENERAL"}
can someone please help me to solve this. or if any have any other idea to authenticate a java application using okhttp then please suggest...
You should use the helper classes to avoid most of the logic for username and password.
https://github.com/square/okhttp/blob/master/samples/guide/src/main/java/okhttp3/recipes/Authenticate.java
String credential = Credentials.basic("jesse", "password1");
return response.request().newBuilder()
.header("Authorization", credential)
.build();
Assuming this API is POST and not GET also follow
https://github.com/square/okhttp/blob/master/samples/guide/src/main/java/okhttp3/recipes/PostString.java
Request request = new Request.Builder()
.url("https://api.github.com/markdown/raw")
.post(RequestBody.create(postBody, MEDIA_TYPE_MARKDOWN))
.build();
You had it all right already. Just a small fix needed:
String basicAuth = "Basic " + new String(Base64.getEncoder().encode(userpass.getBytes()));
i.e you just need to remove extra ':' as it's already taken care of in .addHeader("Authorization", basicAuth) part.
I didn't find any useful way to generate the Signature V4 in java for signing an AWS Chime HttpRequest. I want to use 3 apis of Aws Chime (Create meeting, create attendee and delete meeting) inside my java code.
Can anyone help me please !
API Details:
Url: https://service.chime.aws.amazon.com/meetings
Body: { "ClientRequestToken": "AXEXAMPLE", "MediaRegion":
"us-east-2" }
Headers: "content-type", "application/json" "host",
"service.chime.aws.amazon.com" "x-amz-date", "20200526T094404Z"
"authorization", ?(Generated Signature)
API Key: JHDCHGEXAEXAMPLE Secret Key : 4sjfkkjffs/sfkkh/sfkj/example
private Response createMeeting() {
OkHttpClient client = new OkHttpClient();
Response response = null;
MediaType mediaType = MediaType.parse("application/json");
RequestBody body = RequestBody.create(mediaType, "{\n\t\"ClientRequestToken\": \"AXEXAMPLE\",\n \"MediaRegion\": \"us-east-2\"\n}");
Request request = new Request.Builder()
.url("https://service.chime.aws.amazon.com/meetings")
.post(body)
.addHeader("content-type", "application/json")
.addHeader("host", "service.chime.aws.amazon.com")
.addHeader("content-length", "68")
.addHeader("x-amz-date", getIsoDate())
.addHeader("authorization", "?????????") //To be replaced by generated signature
.addHeader("cache-control", "no-cache")
.build();
try {
response = client.newCall(request).execute();
System.out.println("ResponseMessage===========> " + response.message());
} catch (IOException e) {
System.out.println("Error===========> " + e.getMessage());
}
return response;
}
The error I am getting is: The request signature we calculated does not match the signature you provided. Check your AWS Secret Access Key and signing method. Consult the service documentation for details.
I'm making a request to a website. However, I keep getting a returned JSON of {"error":"invalid_client"}. Additionally, when I navigate to the URL I'm making the request to through a web browser it shows HTTP ERROR 405.
From what I read on those errors that might mean that my request isn't structured correctly.
According to the API's documentation, this is an example of the request type I'm trying to do:
OkHttpClient client = new OkHttpClient();
MediaType mediaType = MediaType.parse("application/x-www-form-urlencoded");
RequestBody body = RequestBody.create(mediaType, "client_secret={your_client_secret}&client_id={your_client_id}&code={your_authorization_code}&grant_type=authorization_code&redirect_uri={your_redirect_uri}");
Request request = new Request.Builder()
.url("https://api.website.com/v2/oauth2/token")
.post(body)
.addHeader("content-type", "application/x-www-form-urlencoded")
.addHeader("cache-control", "no-cache")
.build();
Response response = client.newCall(request).execute();
From what I can tell mine should be doing the same thing, just a little differently.
Here is a Pastebin of my doInBackground method (I'm using AsynchTask). Here is the more applicable part:
OkHttpClient client = new OkHttpClient();
// A section here gets strings from a JSON file storing values such as client_id
RequestBody bodyBuilder = new FormBody.Builder()
.add("client_secret", CLIENT_SECRET)
.add("client_id", CLIENT_ID)
.add("code", AUTHORIZATION_CODE)
.add("grant_type", GRANT_TYPE)
.add("redirect_uri", REDIRECT_URI)
.build();
System.out.println("Built body: " + bodyBuilder.toString());
String mediaTypeString = "application/x-www-form-urlencoded";
MediaType mediaType = MediaType.parse(mediaTypeString);
RequestBody body = RequestBody.create(mediaType, requestbodyToString(bodyBuilder)); // See Edit 1
Request request = new Request.Builder()
.url(TARGET_URL)
.post(body)
.addHeader("content-type", mediaTypeString)
.addHeader("cache-control", "no-cache")
.build();
try {
System.out.println("Starting request.");
Response response = client.newCall(request).execute();
String targetUrl = request.url().toString() + bodyToString(request);
System.out.println("request: " + targetUrl);
String responseBodyString = response.body().string();
System.out.println("response: " + responseBodyString);
return responseBodyString;
} catch (IOException ex) {
System.out.println(ex);
}
Like I said, I keep getting a returned JSON of {"error":"invalid_client"}, and when I navigate to the URL I'm making the request to through a web browser it shows HTTP ERROR 405.
I'd love to provide as much additional information as you need. Thanks!
Edit 1: The second parameter of this used to be "bodyBuilder.toString()", but I changed it because I realized it wasn't actually sending the body. The result is still the same - {"error":"invalid_client"}. The method now used comes from here.
I figured out what it was - I hadn't actually been writing the authentication_code to the file, only adding it to another JSONObject. Oops. :)
I'm trying to use apache http components to interface with the Spotify api. The request I'm trying to send is detailed here under #1. When I send this request from bash using curl
curl -H "Authorization: Basic SOMETOKEN" -d grant_type=client_credentials https://accounts.spotify.com/api/token
I get back a token like the website describes
However the following java code, which as far as I can tell executes the same request, gives back a 400 error
Code
String encoded = "SOMETOKEN";
CloseableHttpResponse response = null;
try {
CloseableHttpClient client = HttpClients.createDefault();
URI auth = new URIBuilder()
.setScheme("https")
.setHost("accounts.spotify.com")
.setPath("/api/token")
.setParameter("grant_type", "client_credentials")
.build();
HttpPost post = new HttpPost(auth);
Header header = new BasicHeader("Authorization", "Basic " + encoded);
post.setHeader(header);
try {
response = client.execute(post);
response.getEntity().writeTo(System.out);
}
finally {
response.close();
}
} catch (Exception e) {
e.printStackTrace();
}
Error
{"error":"server_error","error_description":"Unexpected status: 400"}
The URI that the code prints is looks like this
https://accounts.spotify.com/api/token?grant_type=client_credentials
And the header looks like this
Authorization: Basic SOMETOKEN
Am I not constructing the request correctly? Or am I missing something else?
Use form url-encoding for the data in the body with the content-type application/x-www-form-urlencoded :
CloseableHttpClient client = HttpClients.createDefault();
HttpPost post = new HttpPost("https://accounts.spotify.com/api/token");
post.setHeader(HttpHeaders.CONTENT_TYPE, "application/x-www-form-urlencoded");
post.setHeader(HttpHeaders.AUTHORIZATION, "Basic " + encoded);
StringEntity data = new StringEntity("grant_type=client_credentials");
post.setEntity(data);
HttpResponse response = client.execute(post);
I have this request for twitter using javax.ws.rs
WebTarget target = new WebTargetBuilder(client, OAUTH_API_ENDPOINT).build();
Builder request = target
.request(MediaType.APPLICATION_JSON)
.header("Authorization", "Basic " + encodedCredentials)
.header("Content-Type", "application/x-www-form-urlencoded;charset=UTF-8");
Response postResponse = request
.post(Entity.entity("grant_type=client_credentials", MediaType.TEXT_PLAIN));
System.out.println(postResponse.readEntity(String.class));
encodedCredentials are my consumer secret and consumer key encoded in base 64.
The request I'm trying to do is:
POST /oauth2/token HTTP/1.1
Host: api.twitter.com
User-Agent: My Twitter App v1.0.23
Authorization: Basic eHZ6MWV2RlM0d0VFUFRHRUZQSEJvZzpMOHFxOVBaeVJn
NmllS0dFS2hab2xHQzB2SldMdzhpRUo4OERSZHlPZw==Content-Type: application/x-www- form-urlencoded;charset=UTF-8
Content-Length: 29
Accept-Encoding: gzip
grant_type=client_credentials
I keep getting 403 Forbidden: {"errors":[{"code":170,"message":"Missing required parameter: grant_type","label":"forbidden_missing_parameter"}]}
It seems that the post body isn't set correctly, anyone know how to set it?
What you could try is to change the content type of the POST request body/entity like this:
.post(Entity.entity("grant_type=client_credentials", MediaType.APPLICATION_FORM_URLENCODED)
I have used same in PHP and i think you missed required parameters like oauth_signature
So the final code to obtain the bearer token from Twitter having the consumer key and consumer secret looks like this:
private static final String OAUTH_API_ENDPOINT = "https://api.twitter.com/oauth2/token";
private String consumerKey = "your consumer key";
private String consumerSecret = "your consumer secret";
// Constructs the request for requesting a bearer token and returns that
// token as a string
public String requestBearerToken() throws IOException, InterruptedException, ExecutionException {
String encodedCredentials = encodeCredentials();
Client client = ClientBuilder.newClient();
WebTarget target = new WebTargetBuilder(client, OAUTH_API_ENDPOINT).build();
Response postResponse = target
.request(MediaType.APPLICATION_JSON)
.header("Authorization", "Basic " + encodedCredentials + "Content-Type: application/x-www-form-urlencoded;charset=UTF-8")
.post(Entity.entity("grant_type=client_credentials", MediaType.APPLICATION_FORM_URLENCODED));
return postResponse.toString();
}
// Encodes the consumer key and secret to create the basic authorization key
public String encodeCredentials() {
try {
String encodedConsumerKey = URLEncoder.encode(consumerKey, "UTF-8");
String encodedConsumerSecret = URLEncoder.encode(consumerSecret,
"UTF-8");
String fullKey = encodedConsumerKey + ":" + encodedConsumerSecret;
byte[] encodedBytes = Base64.encodeBase64(fullKey.getBytes());
return new String(encodedBytes);
} catch (UnsupportedEncodingException e) {
return new String();
}
}