I am trying to load a url with headers and trying to get my accessToken
Here is the code
String oauthToken = urls[0];
String tokenVerifier = urls[1];
String responseBody = null;
try {
String url = "https://api.copy.com/oauth/access?oauth_verifier=" + tokenVerifier;
String uniqueID = UUID.randomUUID().toString();
String authorization = "OAuth oauth_version=\"1.0\", oauth_signature_method=\"PLAINTEXT\", oauth_consumer_key=\""+ Constants.COPY_CONSUMER_KEY
+"\", oauth_signature=\""+ Constants.COPY_SECRET +"&" + tokenVerifier "\", oauth_nonce=\""+ uniqueID
+"\", oauth_timestamp=\""+String.valueOf(Calendar.getInstance().getTimeInMillis())+"\" , oauth_token=\""+ oauthToken +"\"";
The response gives me error
oauth_problem=signature_invalid&debug_sbs=GET&https%3A%2F%2Fapi.copy.com%2Foauth%2Faccess&oauth_consumer_key%3DCtu6CtdN1PWRo5DstoxgaaIQWZkeeWNg%26oauth_nonce%3D10525625%26oauth_signature_method%3DHMAC-SHA1%26oauth_timestamp%3D1425400347545%26oauth_token%3D6aNkypb7wZoI7dbJiSrtItOTGmpaG0RL%26oauth_verifier%3D496cb46091352c4788603dcfb6e0cfb5%26oauth_version%3D1.0oauth_error_code=2000
What is wrong with my signature, same method is working for ios
You are sending the ouath_token that you have just received when you have to calculate a new Token using that received token and the request_token_secret. This new token is what you need to send as oauth_token parameter in your request.
Check my python code here.
Related
My code looks like:
ApiClient client = new ApiClient(DEMO_REST_BASEPATH);
String clientId = "65f9b5d9-XXXX-4de6-ab3c-XXXX";
java.util.List<String> scopes = new ArrayList<String>();
scopes.add(OAuth.Scope_SIGNATURE);
byte[] key = Files.readAllBytes(Paths.get("/tmp/privateKey"));
OAuth.OAuthToken token = client.requestJWTApplicationToken(clientId, scopes, key, 3600);
System.err.println(token.getAccessToken());
OAuth.UserInfo userInfo = client.getUserInfo(token.getAccessToken());
System.out.println("UserInfo: " + userInfo);
I see I get an auth token back, however I get an error message when trying to get UserInfo:
Exception in thread "main" com.docusign.esign.client.ApiException: Error while requesting server, received a non successful HTTP code 401 with response Body: '{"error":"internal_server_error","reference_id":"22e7cf18-74b4-48aa-b916-81bde96071ae"}'
at com.docusign.esign.client.ApiClient.getUserInfo(ApiClient.java:760)
Any ideas?
You are missing this line: (example on GitHub)
client.setAccessToken(oAuthToken.getAccessToken(), oAuthToken.getExpiresIn());
Your code should be something like this:
ApiClient client = new ApiClient(DEMO_REST_BASEPATH);
String clientId = "65f9b5d9-XXXX-4de6-ab3c-XXXX";
java.util.List<String> scopes = new ArrayList<String>();
scopes.add(OAuth.Scope_SIGNATURE);
byte[] key = Files.readAllBytes(Paths.get("/tmp/privateKey"));
OAuth.OAuthToken token = client.requestJWTApplicationToken(clientId, scopes, key, 3600);
System.err.println(token.getAccessToken());
client.setAccessToken(oAuthToken.getAccessToken(), oAuthToken.getExpiresIn());
OAuth.UserInfo userInfo = client.getUserInfo(token.getAccessToken());
System.out.println("UserInfo: " + userInfo);
How can I get the name and email from a token .
Structure of the token using jwt.io
http://prntscr.com/yzyf2b
Any help is appreciated.
Update full solution with the help of below posts so credits to them .
String jwtToken = token;
System.out.println("------------ Decode JWT ------------");
String[] split_string = jwtToken.split("\\.");
String base64EncodedHeader = split_string[0];
String base64EncodedBody = split_string[1];
String base64EncodedSignature = split_string[2];
System.out.println("~~~~~~~~~ JWT Header ~~~~~~~");
Base64 base64Url = new Base64(true);
String header = new String(base64Url.decode(base64EncodedHeader));
System.out.println("JWT Header : " + header);
System.out.println("~~~~~~~~~ JWT Body ~~~~~~~");
String body = new String(base64Url.decode(base64EncodedBody));
System.out.println("JWT Body : " + body);
JSONObject jsonObject = new JSONObject(body);
System.out.println(jsonObject.get("email"));
System.out.println(jsonObject.get("name"));
A JWToken has the following structure Header.Body.Signature. Hence, first you should split the token into three parts, namely Header, Body and Signature.
For that you can use
String[] token_part = jwtToken.split("\\.");
then apply what you already have done but for the token_part[1] (i.e., the payload or Body), namely:
sun.misc.BASE64Decoder decoder = new sun.misc.BASE64Decoder();
String a = new String(decoder.decodeBuffer(token_part[1]));
For the decoding part, alternatively, you can try this SO thread.
After that you can use the org.json.JSONObject to parse the JSON. An example:
public class Token {
public static void main(String[] args) {
String token = "{\"name\":\"john doe\", \"email\": \"john#mail.com\"}";
JSONObject jsonObject = new JSONObject(token);
System.out.println(jsonObject.get("email"));
System.out.println(jsonObject.get("name"));
}
}
Output:
john#mail.com
john doe
Full Example:
String jwtToken = token;
System.out.println("------------ Decode JWT ------------");
String[] split_string = jwtToken.split("\\.");
String base64EncodedHeader = split_string[0];
String base64EncodedBody = split_string[1];
String base64EncodedSignature = split_string[2];
System.out.println("~~~~~~~~~ JWT Header ~~~~~~~");
Base64 base64Url = new Base64(true);
String header = new String(base64Url.decode(base64EncodedHeader));
System.out.println("JWT Header : " + header);
System.out.println("~~~~~~~~~ JWT Body ~~~~~~~");
String body = new String(base64Url.decode(base64EncodedBody));
System.out.println("JWT Body : " + body);
JSONObject jsonObject = new JSONObject(body);
System.out.println(jsonObject.get("email"));
System.out.println(jsonObject.get("name"));
I was trying to make Jira cloud rest api call using JWT authentication.
I've followed the steps found in atlassian documentation but I've got this exception:
com.atlassian.jwt.exception.JwtInvalidClaimException: Expecting claim 'qsh' to have value 'qsh value' but instead it has the value 'qsh value'
Thanks in advance
Here is the answer
//1-First we need to create the qsh 'Query String Hash'
String httpMethod = "GET";
String restApiPath = "rest api url without the base url";
String urlParameters = "key=value&key1=value1";
String qsh = String.format("%s%s%s%s%s", httpMethod, "&", restApiPath, "&", urlParameters);
//2-Encode qsh
String encodedQsh = JwtUtil.computeSha256Hash(qsh);
//3-Create JwtJsonBuilder
JwtJsonBuilder jwtJsonBuilder = new JsonSmartJwtJsonBuilder();
jwtJsonBuilder.issuedAt(issuedAt);
jwtJsonBuilder.expirationTime(expiresAt);
jwtJsonBuilder.issuer(issuer);
jwtJsonBuilder.subject(subject);
jwtJsonBuilder.type("JWT");
jwtJsonBuilder.queryHash(encodedQsh);
//4-Encode JWT token
String encodedJwt = new NimbusJwtWriterFactory().macSigningWriter(SigningAlgorithm.HS256, "shared-secret- value").jsonToJwt(jwtJsonBuilder.build());
//5-Build your URL
String urlStrg = baseUrl + restApiPath + "?" + urlParameters
//6-Open Url Connection
URL url = new URL(urlStrg);
httpURLConnection = (HttpURLConnection) url.openConnection();
httpURLConnection.setRequestProperty("Accept", "application/json");
httpURLConnection.setRequestProperty("Authorization", "JWT " + encodedJwtToken);
httpURLConnection.setRequestMethod(httpMethod);
int responseCode = httpURLConnection.getResponseCode();
//responseCode to check if the request is valid and authenticated
Want get result without username and password
Below i put my code to get confluence details:
String userpass = "admin" + ":" + "admin";
String basicAuth = "Basic " + new String(new Base64().encode(userpass.getBytes()));
String jsonPattern = null;
// get value from JSON URL
String sURL = "http://aa875db5.ngrok.io/confluence/rest/api/content?title="
+ java.net.URLEncoder.encode(map.get("Page").trim(), "UTF-8");
============================================================
Without URL,Username and password want get result
I don't have any error in this code but when put in Server.I want give server details that is the problem?
I am trying to create a signed URL in my App Engine code and pass it to the client to make the initial POST call to get the resumable upload location, following the following advice from the documentation:
Performing a resumable upload in a region where it wasn't initiated can
cause slow uploads. To avoid this, you can have the initial POST
request constructed and signed by the server, but then give the signed
URL to the client so that the upload is initiated from their location.
However, when a client makes a POST call to the signed URL, this call results in error 401, which tells me that Cloud Storage expects an authorization header.
This is how my signed URL looks like:
https://www.googleapis.com/upload/storage/v1/b/myBucket/o?uploadType=resumable&name=fileName&GoogleAccessId=xxx#appspot.gserviceaccount.com&Expires=1463628862&Signature=IZNU%2B2ApaUlogY9CR%2B4DC09WKkIpeZLeuqzrudyxA0nETH7Wpr4x8aRZTZj%2BGOriCDL8JfnoyAFhY1XqMG7VU3VPliu7LXoDSvuH0Cjaoz5lefNs80HpneAHI7HpAX2Uv2Lr57ZwbXM3EoegGiTcJb3ck51VH0%2FxTWSnqxlJsgQzo9%2BYKVhkHBzFn29k7k76qsGhN91g5CfTtSKtfa%2FiYwCffoB%2BctIdULwKF7yMugNkLKAfqxrWRXVAmrzXUK9njGTOQqfcvAtq4jJ23Aflo6ETmDKghZuZNLqoHs5umEhFRC1eFGd%2Be10RDRON%2F1ysXahWawSx4YOE9bEZXPKNtQ%3D%3D
I use the same code on the App Engine side to generate signed URLs for downloads and they work just fine.
Is this the correct way to assemble the URL for the initial POST call? Is there something else causing this error?
EDIT
Code to generate URL:
long expiration = System.currentTimeMillis()/1000 + 60;
String unsigned = stringToSign(expiration, gsKey, "POST");
String signature = sign(unsigned);
return new StringBuilder("https://www.googleapis.com/upload/storage/v1/b/")
.append(BUCKET)
.append("/o?uploadType=resumable&name=")
.append(gsKey)
.append("&GoogleAccessId=")
.append(identityService.getServiceAccountName())
.append("&Expires=")
.append(expiration)
.append("&Signature=")
.append(URLEncoder.encode(signature, "UTF-8"))
.toString();
private static String stringToSign(final long expiration, String gsKey, String httpVerb) {
String contentType = "";
String contentMD5 = "";
String canonicalizedExtensionHeaders = "";
String canonicalizedResource = "/" + BUCKET + "/" + gsKey;
String stringToSign = httpVerb + "\n" +
contentMD5 + "\n" +
contentType + "\n" +
expiration + "\n" +
canonicalizedExtensionHeaders + "\n" +
canonicalizedResource;
return stringToSign;
}
private static String sign(final String stringToSign) throws UnsupportedEncodingException {
SigningResult signingResult = identityService.signForApp(stringToSign.getBytes());
String encodedSignature = new String(Base64.encodeBase64(signingResult.getSignature(), false), "UTF-8");
return encodedSignature;
}