Yahoo Oauth inconsistent "Invalid Signature" - java

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

Related

Send embedded signing email with setting signing order

So basically I need to use embedded signing feature to get the URL and embed into my application, and then my customer can sign the document from my side. Apart from that, after my customer signed on the doc, he needs to ask his debtor to sign on the same doc as well.
So on DocuSign UI, I found that I can set a signing order, which means the second recipient receives the email right after the first recipient signed (perfect match my requirement).
setting on UI
However, the second recipient can not receive the email after the first signer signed even though on UI it says sent.
public Envelope embeddedSigning(Long debtorId, String signerEmail, String signerName, String templateId) throws ApiException, IOException {
// create an envelop
EnvelopeDefinition envelope = makeEnvelope(debtorId, signerEmail, signerName, templateId);
ApiClient apiClient = baseRestApiClient();
apiClient.addDefaultHeader("Authorization", "Bearer " + getToken());
EnvelopesApi envelopesApi = new EnvelopesApi(apiClient);
EnvelopeSummary summary = envelopesApi.createEnvelope(accountId, envelope);
RecipientViewRequest viewRequest = makeRecipientViewRequest(debtorId, signerEmail, signerName);
ViewUrl viewUrl = envelopesApi.createRecipientView(accountId, summary.getEnvelopeId(), viewRequest);
// #formatter:off
return Envelope.builder()
.envelopId(summary.getEnvelopeId())
.redirectUrl(viewUrl.getUrl()).build();
// #formatter:on
}
private EnvelopeDefinition makeEnvelope(Long debtorId, String signerEmail, String signerName, String templateId) throws IOException {
EnvelopeDefinition envelopeDefinition = new EnvelopeDefinition();
envelopeDefinition.setEmailSubject("Please sign this document");
envelopeDefinition.setTemplateId(templateId);
TemplateRole signer = new TemplateRole();
signer.setEmail(signerEmail);
signer.setName(signerName);
signer.clientUserId(String.valueOf(debtorId));
signer.setRoleName("signer0");
signer.setRoutingOrder("1");
TemplateRole signer1 = new TemplateRole();
signer1.setEmail("xxx");
signer1.setName("xxx");
signer1.clientUserId(String.valueOf(xxx));
signer1.setRoleName("signer1");
signer1.setRoutingOrder("2");
envelopeDefinition.setTemplateRoles(Arrays.asList(signer, signer1));
envelopeDefinition.setStatus("sent");
return envelopeDefinition;
}
You are setting signer1.clientUserId(String.valueOf(xxx)); which means you are making signer an embedded signer. By Default, DocuSign does not send email to the embedded signer. By making a signer as embedded signer, you are telling DocuSign that calling App will take care of deciding when to host signing ceremony for this signer so DocuSign will not send an email as they will not be doing signing from the email, instead it be your App which will be generating Signing URL when that signer is on your App. So if you remove signer1.clientUserId(String.valueOf(xxx)); code then you will see that signer1 will get an email from DocuSign.
Docs has more details about embedded signing.
Typically routing order starts at 1. so it should be 1 and 2, not 0 and 1.
Apart from that, "Sent" is the status for the entire envelope. The envelope goes to routing order 1 first. Then, when all recipients of routing order 1 finished signing, it goes to 2 etc. I'm not sure if you actually have an issue here, but please confirm after you changed to 1 and 2 what exactly do you see that you don't expect.

Subject must match Issuer claim in the client assertion

I want to integrate office365 service management API for collecting events from it.I want to use client credential way to use service to service call but i am getting following error,
{
"error":"invalid_client",
"error_description":"AADSTS50048: Subject must match Issuer claim in the client assertion.
\r\nTrace ID: 1ad7acd8-3945-4fe0-a313-07638eb76e42\r\nCorrelation ID: a6c3a3c9-b737-4bfc-894f-3086c3ce8dfa\r\nTimestamp: 2016-06-09 07:20:15Z",
"error_codes":[50048
],
"timestamp":"2016-06-09 07:20:15Z",
"trace_id":"1ad7acd8-3945-4fe0-a313-07638eb76e42",
"correlation_id":"a6c3a3c9-b737-4bfc-894f-3086c3ce8dfa"
}
i use following doc to integration,
For getting client assersion,
https://msdn.microsoft.com/en-us/library/azure/dn645543.aspx I am getting this. But for Access token,
https://msdn.microsoft.com/en-us/library/office/dn707383.aspx I not getting this as a response getting above error.
Somebody help me please :)
How did you get the client_assertion? The link you provide doesn’t describe how to get the ‘client_assertion’. It acquire the token with the app’s id and secret which is doesn’t support for the Office 365 Management API. You can refer the blog to about the ‘client_assertion’.
And here is an C# code sample which use the ADAL to get the access token for the client credentials flow:
string clientId = "{clientId}";
string certThumbprint = "‎{copy from mmc}";
certThumbprint = certThumbprint.Replace("\u200e", string.Empty).Replace("\u200f", string.Empty).Replace(" ", string.Empty);
string apiResourceId = "https://manage.office.com";
X509Certificate2 cert = null;
X509Store store = new X509Store(StoreName.My, StoreLocation.CurrentUser);
string authority = "https://login.windows.net/{yourTentant}";
var authContext = new AuthenticationContext(authority);
try
{
store.Open(OpenFlags.ReadOnly);
cert = store.Certificates.Find(X509FindType.FindByThumbprint, certThumbprint, false)[0];
}
finally
{
store.Close();
}
var certCred = new ClientAssertionCertificate(clientId, cert);
AuthenticationResult result = null;
try
{
result = await authContext.AcquireTokenAsync(apiResourceId, certCred);
}
catch (Exception ex)
{
}

Getting one field from response entity json

i need to connect to a rest service to get the user id by using a token.
List<Object> providers = new ArrayList<>();
providers.add(new JacksonJaxbJsonProvider());
client = WebClient.create(properties.getProperty(URL), providers);
client = client.accept(MediaType.APPLICATION_JSON_TYPE).type(MediaType.APPLICATION_JSON_TYPE);
client.path(PATH + token);
Response response = client.get();
The entity of response have this format:
{"message":"Token is valid","userId":1}
To get the userId, i have:
response.readEntity(AuthResponse.class).userId;
It is possible to take only the userId without creating an class with that format ? (without AuthResponse.class)
You can try to read your JSON as Map, for example: response.readEntity(Map.class).get("userId")
Please refer to this page for more information.

How to access wsdl in grails - 400 status code return

I want to send the data to person object. How to do it with PostMethod.
def payload ='<person><nationalId>'+1234567+'</nationalId></person>'
def method = new PostMethod(url)
def client = new HttpClient()
payload = payload.trim()
method.addRequestHeader("Content-Type","text/xml")
method.addRequestHeader("Accept","text/xml,application/xml;q=0.9")
Credentials credentials = new UsernamePasswordCredentials('simple', 'simple');
client.getState().setCredentials(new AuthScope(AuthScope.ANY_HOST,8080, AuthScope.ANY_REALM, "digest"),credentials);
method.setRequestEntity(new StringRequestEntity(payload))
def statusCode = client.executeMethod(method)
println "STATUS CODE : ${statusCode}"
def resultsString = method.getResponseBodyAsString()
method.releaseConnection()
println resultsString
I tried above coding. How to set password and username and password digest also. For that i think status code 400 is coming.Please notify where i made mistake
Try to look at REST Client Builder Plugin. See docs and I guess, you'll find more convenient way to send request

Blogger JSON API add a post

I want to add post to my blog using Blogger API. I successfully got rights to use Blogger API and activated them in Google API console. I used this tutorial to obtain access_token. I found this question , so before ever request I obtain new request_token.
When I make first request to add post, I got en error: 401 "message": "Invalid Credentials", "location": "Authorization".
When I make second request to add post with new token, I got error: 403 "message": "Daily Limit Exceeded. Please sign up"
Code for my request is:
final JSONObject obj = new JSONObject();
obj.put("id", mUserID);
final JSONObject requestBody = new JSONObject();
requestBody.put("kind", "blogger#post");
requestBody.put("blog", obj);
requestBody.put("title", msg[0]);
requestBody.put("content", msg[0] + " " + msg[1]);
final HttpPost request = new HttpPost("https://www.googleapis.com/blogger/v3/blogs/" + mUserID + "/posts");
request.addHeader("Authorization", "Bearer " + mToken);
request.addHeader("Content-Type", "application/json");
request.setEntity(new StringEntity(requestBody.toString()));
final HttpResponse response = mHttpClient.execute(request);
final HttpEntity ent = response.getEntity();
Log.i(SocialPoster.LOG, EntityUtils.toString(ent));
ent.consumeContent();
UPDATE
Solution was found: simply adding "?key={MY_API_KEY}" to request's URL solved the problem
The Tutorial site you linked states
"The API Key is mandatory as it identifies your application and therefore allows the API to deduct quota and use the quota rules defined for your project. You need to specify the API Key on your Tasks service Object."
useTasksAPI(String accessToken) {
// Setting up the Tasks API Service
HttpTransport transport = AndroidHttp.newCompatibleTransport();
AccessProtectedResource accessProtectedResource = new GoogleAccessProtectedResource(accessToken);
Tasks service = new Tasks(transport, accessProtectedResource, new JacksonFactory());
service.accessKey = INSERT_YOUR_API_KEY;
service.setApplicationName("Google-TasksSample/1.0");
// TODO: now use the service to query the Tasks API
}
Sounds to me like you are missing the API key, using it wrong, misplaced it in your code or supplied it to the service in the wrong way.
I haven't looked over the code here, but this is Google's sample code for what you are trying to do. Test your API key with this code.

Categories