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”).我的代码如下:
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

猜你在找的Java相关文章