java – 使用OAuth-Signpost和Apache HttpComponents签署POST请求的正确方法是什么?

前端之家收集整理的这篇文章主要介绍了java – 使用OAuth-Signpost和Apache HttpComponents签署POST请求的正确方法是什么?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我正在使用OAuth-Signpost Java库来签署从客户端发送到实现OAuth身份验证的服务器的请求.当GET请求(使用HttpURLConnection)时,一切都正常:请求被签名,参数被包括,签名在目的地匹配.但是,它似乎不适用于POST请求.我知道在使用HttpURLConnection签名POST时可能出现的问题,所以我转移到Apache HttpComponents库以获得这些请求.在以下示例中发送的参数是纯字符串和类似XML的字符串(“rxml”).我的代码如下:
  1. public Response exampleMethod(String user,String sp,String ep,String rn,String rxml){
  2.  
  3. //All these variables are proved to be correct (they work right in GET requests)
  4. String uri = "...";
  5. String consumerKey = "...";
  6. String consumerSecret = "...";
  7. String token = "...";
  8. String secret = "...";
  9.  
  10. //create the parameters list
  11. List<NameValuePair> params = new ArrayList<NameValuePair>();
  12. params.add(new BasicNameValuePair("user",user));
  13. params.add(new BasicNameValuePair("sp",sp));
  14. params.add(new BasicNameValuePair("ep",ep));
  15. params.add(new BasicNameValuePair("rn",rn));
  16. params.add(new BasicNameValuePair("rxml",rxml));
  17.  
  18. // create a consumer object and configure it with the access
  19. // token and token secret obtained from the service provider
  20. OAuthConsumer consumer = new CommonsHttpOAuthConsumer(consumerKey,consumerSecret);
  21. consumer.setTokenWithSecret(token,secret);
  22.  
  23. // create an HTTP request to a protected resource
  24. HttpPost request = new HttpPost(uri);
  25.  
  26. // sign the request
  27. consumer.sign(request);
  28.  
  29. // set the parameters into the request
  30. request.setEntity(new UrlEncodedFormEntity(params));
  31.  
  32. // send the request
  33. HttpClient httpClient = new DefaultHttpClient();
  34. HttpResponse response = httpClient.execute(request);
  35.  
  36. //if request was unsuccessful
  37. if(response.getStatusLine().getStatusCode()!=200){
  38. return Response.status(response.getStatusLine().getStatusCode()).build();
  39. }
  40.  
  41. //if successful,return the response body
  42. HttpEntity resEntity = response.getEntity();
  43. String responseBody = "";
  44.  
  45. if (resEntity != null) {
  46. responseBody = EntityUtils.toString(resEntity);
  47. }
  48.  
  49. EntityUtils.consume(resEntity);
  50.  
  51. httpClient.getConnectionManager().shutdown();
  52.  
  53. return Response.status(200).entity(responseBody).build();
  54.  
  55. }

当我向服务器发送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中的错误.您需要将方法实现添加到它们,但是不同的风格.首先你会添加

  1. public void setMethod(String method){
  2. try {
  3. this.connection.setRequestMethod(method);
  4. } catch (ProtocolException e) {
  5.  
  6. e.printStackTrace();
  7. }
  8. }

第二个你会添加

  1. public void setMethod(String method){
  2.  
  3. try {
  4. RequestWrapper wrapper = new RequestWrapper(this.request);
  5. wrapper.setMethod(method);
  6. request = wrapper;
  7. } catch (org.apache.http.ProtocolException e) {
  8. e.printStackTrace();
  9. }
  10. }

最后你会添加

  1. public void setMethod(String method){
  2. mMethod = method;
  3. }

被警告,我只使用和尝试了第一个和最后一个.但是,至少如果你有一样的话,这个问题至少给你一个解决问题的想法.

希望这有助于反正.

-MrDresden

猜你在找的Java相关文章