zhmq121 / oauth

Automatically exported from code.google.com/p/oauth
0 stars 0 forks source link

Authentication failure when using PUT method #180

Open GoogleCodeExporter opened 9 years ago

GoogleCodeExporter commented 9 years ago
1. perform PUT request using OAuth using following code

import net.oauth.OAuth;
import net.oauth.OAuthAccessor;
import net.oauth.OAuthConsumer;
import net.oauth.OAuthMessage;
import net.oauth.ParameterStyle;
import net.oauth.client.OAuthClient;
import net.oauth.client.httpclient3.HttpClient3;
import net.oauth.signature.RSA_SHA1;

public class XeroTest
{

  public static void main(String[] args)
  {
    String apiURL="https://api.xero.com/api.xro/2.0/";

    String consumer_privateRSAKey="-----BEGIN RSA PRIVATE KEY-----\n"
        + "MIICXAIBAAKBgQDbpie9UmO0nRLMTIf3tNzqf1ARnNeFQHvaV6XHeNY9kfUvnHv8\n"
        + "8UuQLgB49BArG4AABv7QRAF7Azqn7jY6LgunMnW+rc9lxJsfGJuhRILc5Zh21Qmq\n"
        + "NOZLmSsZyLDoWo1VresG6eMqQBaqBb26u73aBccznC5ayuCYU1+EyWb0iwIDAQAB\n"
        + "AoGAJ4O2tnpx8XYogZRrCYcCDzWkI+cBZrl5DoiiDEaS1DTD1TLjo1eNbny4HQpb\n"
        + "NkYWOusHQFRbp9Om47sZClJqSe58ApkhWgFGneCjFCJCjP0WnBnF1wTgAkgLfgq+\n"
        + "3r2K2+Gptwhdg9ZimXgY3+mY5U+cJvJ/rbiPeCLWVs7HO1ECQQD57MrgaVpaSell\n"
        + "phzdlsy1iI4+4OY6ydXY6D2YBjqx4TpxahUOmFjN74/5XBZc3gn+1kMGtfW0ZFC4\n"
        + "hVmWd1h1AkEA4Pz2/bvJnD6OAGlRvM4de+/rtHjp9bPoLdTby0oFlr7sMafiImnG\n"
        + "5TlM+QFzrdmKGWi95A8UnPOwFSy7APN4/wJAN9Fv+jDtcg7h5sbz2XWtoLmv81Et\n"
        + "emHLthcgcoypnULNV7k2nLzf0Ja5lBrCD9mzZ8wYyi3ng3OIJ734pUdgZQJBANmb\n"
        + "cdzp807epgO52efOR3AnFofAZzFRJ6Ckf025M3yg/tvsL+ju/AObD1rLz7H3dP2s\n"
        + "c/WPrHU9sTJZyClcU8sCQF1886+5G+gf3Bg/sJRglRdpQ3jbWnxfRLDTCTnHwmIv\n"
        + "BsUN0XGNJ4SxChvc5rLvpTHpjTZYgZohJhuaI6WNFzg=\n"
        + "-----END RSA PRIVATE KEY-----";

    String consumerKey="MZFHMTC3NWFLZTCXNGE4YTG3NGVJMJ";
    String consumerSecret="OQDTQCDEXS21UURUVTSURLE9ARQ7UP";

    OAuthConsumer consumer = new OAuthConsumer(null,consumerKey, null, null);
    consumer.setProperty(RSA_SHA1.PRIVATE_KEY, consumer_privateRSAKey);
    consumer.setProperty(OAuth.OAUTH_SIGNATURE_METHOD, OAuth.RSA_SHA1);
    consumer.setProperty(OAuthClient.PARAMETER_STYLE, ParameterStyle.AUTHORIZATION_HEADER);

    OAuthAccessor myAccessor = new OAuthAccessor(consumer);
    myAccessor.accessToken = consumerKey;
    myAccessor.tokenSecret = consumerSecret;

    try {
      // PUT Contacts example
      String postXML="<Contact>" +
            "<Name>Contact Name</Name>" +
            "<ContactNumber>002</ContactNumber>" +
            "</Contact>";
      OAuthClient client = new OAuthClient(new HttpClient3());
      OAuthMessage m = client.invoke(myAccessor, OAuthMessage.PUT, apiURL+"Contacts", OAuth.newList("xml",postXML));
      System.out.println(OAuthMessage.readAll(m.getBodyAsStream(), "UTF-8"));
    }
    catch ( Exception e ) {
      System.out.println(e.toString());
    }

  }
}

I expect to see a response from Xero with the newly created contact (like if I 
were to use POST method); instead the following is printed
11/08/2010 3:41:16 PM org.apache.commons.httpclient.HttpMethodDirector 
processWWWAuthChallenge
WARNING: Unable to respond to any of these challenges: {oauth=OAuth 
Realm="203.92.29.151"}
oauth_problem=signature_invalid&oauth_problem_advice=Failed%20to%20validate%20si
gnature

I am using version from svn checkout of r1236

Original issue reported on code.google.com by hippysoy...@gmail.com on 11 Aug 2010 at 6:05

GoogleCodeExporter commented 9 years ago
Gah, I'm not doing anything right today. Please disregard this ticket, the 
issue is that I was screwing around with the code that generates the signature

Original comment by hippysoy...@gmail.com on 11 Aug 2010 at 6:20

GoogleCodeExporter commented 9 years ago
Hi,

we are experiencing problems with the put request in connection with the XERO 
API.
The authentication seems ok, however OAuth puts the actual PUT params into the 
request header and NOT in the req body.
The post request works.
In order to update Payments for approved invoices in Xero only the PUT method 
can be used.

Original comment by ukuhnha...@gmail.com on 9 Sep 2010 at 12:51

GoogleCodeExporter commented 9 years ago
Hi, 

The issue here is that Xero don't support the full OAuth v1.0a spec - as I 
understand it it's completely valid to put the params into the request header, 
but Xero don't support it. 
The difficulty with putting the params in the body is that depending on if you 
use v1.0 or v1.0a the parameters are included or not included in the signature 
- ie it's not possible to support both versions simultaneously. 

I'd be very happy to be corrected if someone knows otherwise!

Original comment by hippysoy...@gmail.com on 9 Sep 2010 at 1:00

GoogleCodeExporter commented 9 years ago

Original comment by morten.f...@gmail.com on 29 Mar 2011 at 6:00

GoogleCodeExporter commented 9 years ago
I am trying to create a New Invoice through Xero's API but somehow i am getting 
the response as 
"oauth_problem=signature_invalid&oauth_problem_advice=Failed%20to%20validate%20s
ignature".  I am playing with it from couple of days but i didn't manage to 
create the Invoice on Xero. Below is my function that i am using to create a 
new Invoice. It is written in Groovy. 

def createInvoiceByPost(def invoice,String key,String secret,String verifier) {
        try {

            def config = conf.config
            String consumerName = config.consumerName
            String apiUrl = config.invoiceUrl
            String xml = invoiceService.convertToXml(invoice)

            xml="<?xml version=\"1.0\" encoding=\"UTF-8\"?> "+xml
            xml = URLEncoder.encode(xml,"UTF-8")

            String body = "<form enctype=\"application/x-www-form-urlencoded;charset=UTF-8\" method=\"post\">"+
                          " <input type=\"hidden\" id=\"xml\" name=\"xml\" value=\"${xml}\"/>"+
                          "</form>"
            //body = URLEncoder.encode(body,"UTF-8")
            def resp = oauthService.accessResource(apiUrl,consumerName,["key":key,"secret":secret],
                          "post",["oauth_verifier":verifier,"${OAuth.OAUTH_SIGNATURE_METHOD}":OAuth.HMAC_SHA1,"${OAuthClient.PARAMETER_STYLE}":ParameterStyle.AUTHORIZATION_HEADER],
                          [],body,null,
                          "application/x-www-form-urlencoded; charset=utf-8")
            return resp
        }
        catch(Exception exp) {
            println exp.toString()
        }
    }

Can anybody tell me where i am making any mistake. I have to create a new 
Invoice. Off-course it will be created as Draft. I have tested the XML that my 
"convertToXml" function generated. I pasted that XML on API viewer and executed 
that and that worked fine. The Invoice was generated but i am not able to 
generate it through my code. 

Any help will be highly appreciated. 

Original comment by sikander...@gmail.com on 1 Feb 2012 at 11:54

GoogleCodeExporter commented 9 years ago
Hi, 

you could be encountering the same error that I had - I ended up checking out 
the OAuth source and modifying it to put the params in the request header as 
per my comment 3 http://code.google.com/p/oauth/issues/detail?id=180#c3. I 
forget if Xero use version 1.0 or 1.0a (you might need to contact Xero), but 
you'll need to look up the spec to see what changes you need to make with the 
generation of the signature.

I can't really submit my changes as they will break compatibility with one of 
the versions. 

hope that helps!

Original comment by hippysoy...@gmail.com on 2 Feb 2012 at 6:25

GoogleCodeExporter commented 9 years ago
In case this helps anyone, I got around this by setting the body myself like 
this:

            parameters = new ArrayList<>(1);
            parameters.add(new OAuth.Parameter("xml", payments.toXml()));
            byte[] form = OAuth.formEncode(parameters).getBytes(UTF_8);

            String url = xeroConfig.getApiBaseUrl() + PAYMENTS_ENDPOINT;
            OAuthMessage request = accessor.newRequestMessage(PUT, url, null, new ByteArrayInputStream(form));
            request.getHeaders().add(new OAuth.Parameter(HttpHeaders.CONTENT_ENCODING, UTF_8));

            request.getHeaders().add(new OAuth.Parameter(HttpHeaders.CONTENT_TYPE, OAuth.FORM_ENCODED));
            request.getHeaders().add(new OAuth.Parameter(HttpHeaders.CONTENT_LENGTH, String.valueOf(form.length)));

//
            OAuthMessage m = oauthClient.invoke(request, ParameterStyle.BODY);

Hope that helps someone else having trouble with the xero API

Cheers
dalyc

Original comment by Mr.Colin...@gmail.com on 3 Dec 2014 at 12:55

GoogleCodeExporter commented 9 years ago
The issue comes from the new HttpMessage not adding the body for put messages. 
In HttpMessage on like 132 it needs to also check for the PUT message type.

        final boolean isPost = OAuthMessage.POST.equalsIgnoreCase(from.method) || OAuthMessage.PUT.equalsIgnoreCase(from.method);

Original comment by plugboy@gmail.com on 28 Jan 2015 at 8:49