public Response exampleMethod(String user,String sp,String ep,String rn,String rxml){ //All these variables are proved to be correct (they work right in GET requests) String uri = "..."; String consumerKey = "..."; String consumerSecret = "..."; String token = "..."; String secret = "..."; //create the parameters list List<NameValuePair> params = new ArrayList<NameValuePair>(); params.add(new BasicNameValuePair("user",user)); params.add(new BasicNameValuePair("sp",sp)); params.add(new BasicNameValuePair("ep",ep)); params.add(new BasicNameValuePair("rn",rn)); params.add(new BasicNameValuePair("rxml",rxml)); // create a consumer object and configure it with the access // token and token secret obtained from the service provider OAuthConsumer consumer = new CommonsHttpOAuthConsumer(consumerKey,consumerSecret); consumer.setTokenWithSecret(token,secret); // create an HTTP request to a protected resource HttpPost request = new HttpPost(uri); // sign the request consumer.sign(request); // set the parameters into the request request.setEntity(new UrlEncodedFormEntity(params)); // send the request HttpClient httpClient = new DefaultHttpClient(); HttpResponse response = httpClient.execute(request); //if request was unsuccessful if(response.getStatusLine().getStatusCode()!=200){ return Response.status(response.getStatusLine().getStatusCode()).build(); } //if successful,return the response body HttpEntity resEntity = response.getEntity(); String responseBody = ""; if (resEntity != null) { responseBody = EntityUtils.toString(resEntity); } EntityUtils.consume(resEntity); httpClient.getConnectionManager().shutdown(); return Response.status(200).entity(responseBody).build(); }
当我向服务器发送POST请求时,我得到一个错误,告诉我签名(我发送的一个和服务器自己计算的一个)不匹配,所以我想这与签名的基本字符串有关以及POST签名的工作方式,因为它们正在处理双方的密钥和秘密(已选中).
我已经看到,通过这种方式将参数设置为URL的一部分(如在GET请求中).这对我来说不行,因为XML参数可能会超过URL长度,因此需要作为POST参数发送.
我想我在签名POST请求或处理参数时出错了,但我不知道是什么.请你帮帮我吗
P.S:如果我缺乏关于这个问题的上下文,错误跟踪或其他信息,我很抱歉,但我在这里是新手.所以请不要犹豫,要求我更多的信息,如果你需要它.
解决方法
过去几天我也遇到过类似的问题,几乎已经放弃了.直到我听说我公司正在提供的服务的人正在与他进行配对,才从查询字符串而不是头参数中读取OAuth信息.
因此,当您将其传递给要签名的Signpost放入请求中的标题参数Authorization时,不需要读取它,例如[授权:OAuth oauth_consumer_key =“USER”,oauth_nonce =“4027096421883800497”,oauth_signature =“Vd + JEb0KnUhEv1E1g3nf4Vl3SSM = “,oauth_signature_method =”HMAC-SHA1“,oauth_timestamp =”1363100774“,oauth_version =”1.0“],尝试读取查询字符串的服务,例如http://myservice.mycompany.com?oauth_consumer_key=USER\u0026amp;oauth_nonce = 4027096421883800497&安培; oauth_signature = Vd的+ JEb0KnUhEv1E1g3nf4Vl3SSM =安培; oauth_signature_method = HMAC-SHA1&安培; oauth_timestamp = 1363100774&安培; oauth_version = 1.0.
这样做的问题是,当我尝试使用它签署url然后构建一个HttpPost请求时,该url获得了一个前缀GET而不是POST的basestring,该引用给出另一个签名,然后是该服务计算的一个签名.路标没有做错事,它的url签名方法只是默认设置为GET,没有其他可用性开箱即用.这样做是因为你应该在POST时读取头参数,而不是查询字符串(去我的那个“同事”的房子),并且Signpost在签名请求时添加这些,你应该在做POST时.
SignbindString类方法可以在Signpost中生成签名边界.
解
现在这是我做的,但其他方式可能甚至更好.
>获取路标源代码并将其添加到您的项目中.可以得到它here
找到OAuthConsumer类并更改签名方法,以便您可以传递请求应为POST的信息.在我的情况下,我添加了一个像这样的公共String标志(String url,boolean POST)的布尔值,
>现在您需要更改AbstractOAuthConsumer类中的符号方法,CommonsHttpOAuthConsumer和DefaultOAuthConsumer将扩展它们.在我的情况下,我将布尔变量添加到方法,并将以下if(POST)request.setMethod(“POST”);在方法调用sign(request)之前;
>现在请求是一个Signpost特定的对象,HTTPRequest,所以这会抛出一个错误.你需要更改它并添加方法public void setMethod(String method);.
>这将导致以下类HttpURLConnectionRequestAdapter,HttpRequestAdapter和UrlStringRequestAdapter中的错误.您需要将方法实现添加到它们,但是不同的风格.首先你会添加
public void setMethod(String method){ try { this.connection.setRequestMethod(method); } catch (ProtocolException e) { e.printStackTrace(); } }
第二个你会添加
public void setMethod(String method){ try { RequestWrapper wrapper = new RequestWrapper(this.request); wrapper.setMethod(method); request = wrapper; } catch (org.apache.http.ProtocolException e) { e.printStackTrace(); } }
最后你会添加
public void setMethod(String method){ mMethod = method; }
被警告,我只使用和尝试了第一个和最后一个.但是,至少如果你有一样的话,这个问题至少给你一个解决问题的想法.
希望这有助于反正.
-MrDresden