【问题标题】:Mimicking Java setRequestProperty with CURL for RESTful Authentication使用 CURL 模仿 Java setRequestProperty 进行 RESTful 身份验证
【发布时间】:2014-09-16 23:05:01
【问题描述】:

我不懂 Java,也没有在 Google 或试错测试中取得成功......

如果只在命令行上使用 CURL 进行 RESTful API 身份验证,我将如何编写它? (php 或 perl 解决方案也可以)

此代码来自文档,但我不打算使用 Java,需要翻译它。

URL url = new URL("http://www.thingsandstuff.com/resfulness/post");

HttpURLConnection conn = (HttpURLConnection) url.openConnection();

// i don't know if this is relevant to my question or not... 
conn.setRequestMethod("POST");
conn.setDoInput(true);
conn.setDoOutput(true);

conn.setRequestProperty("Content-Type","application/x-www-form-urlencoded");

// this is what i think might be the problem... 
String userNamePassword = "myusername:mypassword";
userNamePassword =
      new String(org.apache.commons.codec.binary.Base64.encodeBase64(userNamePassword
      .getBytes()));

conn.setRequestProperty("Authorization", userNamePassword);

我总是收到 401 未经授权的错误。

我一直在玩标题参数-H。我不知道我正在做的事情是否不起作用,因为我确实没有正确进行身份验证,或者是否是其他原因。数据是 xml,我正在用一些非常简单/直接的东西进行测试。我假设即使我的 data/xml/post 不正确,它也会返回错误而不是未经授权。

# bXl1c2VybmFtZTpteXBhc3N3b3Jk == myusername:mypassword base64 encoded.... 

curl -H "bXl1c2VybmFtZTpteXBhc3N3b3Jk" -d "<datums>" -X POST http://www.thingsandstuff/restfulness/post 
curl -H "bXl1c2VybmFtZTpteXBhc3N3b3Jk" -d "<datums>" -X POST  http://www.thingsandstuff/restfulness/post 

# and like this... with encoded things and not encoded things... 

curl -d "<datums>" -X POST  http://user:password@www.thingsandstuff.com/restfulness/post 
curl -u user:password -d "<datums>" -X POST  http://www.thingsandstuff.com/restfulness/post

对于所有这三个,我都尝试过只对密码进行编码,两者都在一起,都分开,两者都没有......而且我确信我的用户名确实有 \ 并且密码没有帮助以! 结尾,但我认为,当我不对其进行编码时,我正在正确地转义。

curl man page 表示-d will cause curl to pass the data to the server using the content-type application/x-www-form-urlencoded,这意味着我不需要传递额外的标题来说明内容类型,对吧?基本上......我只部分知道我在做什么,但它不起作用,有太多我不知道的事情足以隔离我的问题,甚至可能纠正它(是的,刚好够危险) .

【问题讨论】:

  • 也许...我需要两者都做? -u-H?那是一回事吗?

标签: java rest authentication curl restful-authentication


【解决方案1】:

您获得 401 的原因是 Authorization 标头需要一个方案前缀,在您的情况下为 Basic

所以目前你正在发送

Authorization: <base64(username:password)>

但是网络服务器期望

Authorization: Basic <base64(username:password)>

here所述

此更改应该有效:

conn.setRequestProperty("Authorization", "Basic " + userNamePassword);

【讨论】:

  • 我没有使用 Java,所以我不能使用 conn.setRequestProperty
【解决方案2】:

好的,这就是我最终的结果......

curl -H "Authorization:dXNlclxuYW1lOnBhc3N3b3JkIQ==" -X POST -d 'data=%3C%3Fxml+version....' http://www.stuffandthings.com:8080/restfulness/post

所以...username:password 是 base 64 编码在一起的。数据由 ISO/IEC 8859-1 编码,前缀为“data=”这个特定的 set RESTful 服务。

我最终把它放在 PHP 中只是因为这样更容易连续测试。这就是最终为此工作的原因......

$user     = 'user\\name';
$pass     = 'password!';  
$userpass =  base64_encode($user.':'.$pass);
$url      = 'http://www.thingsandstuff.com:8080/restfulness/post';  

if (($handle = fopen("foo.csv", "r")) !== FALSE) 
{
    while (($data = fgetcsv($handle, 1000, ",")) !== FALSE) 
    { 
        list($thing1,$thing2) = $data;

        $xml = "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>
        <entry xmlns=\"http://purl.org/atom/ns#\"> 
            <xml data goes here>
                <ns:thing1>$param1</ns:thing1>
                <ns:thing2>$param2</ns:thing2>
            </xml data goes here>
        </entry>";

        $datums = 'data='.utf8_decode($xml);
        $result = do_curl($url,$datums); 

        // not actually using the response at this
        // point... just running through everything 
        var_dump($result); 
    }
    fclose($handle);
} 

function do_curl($url, $data) {  
    global $userpass, $user, $pass; 

    $ch = curl_init(); 

    $header = array('Authorization:'.$userpass,
                    'Content-Type:application/x-www-form-urlencoded',
                    'Content-Length:'.strlen($data)); 

    // this line was the last thing to be added before it worked
    // i didn't try it again, removing the authentication in $header
    // to see if this was the only thing actually needed...  
    curl_setopt($ch, CURLOPT_USERPWD, $user.':'.$pass); 

    curl_setopt($ch, CURLOPT_URL, $url);  
    curl_setopt($ch, CURLOPT_HEADER, $header); 
    curl_setopt($ch, CURLINFO_HEADER_OUT, true); 
    curl_setopt($ch, CURLOPT_NOBODY, true); 
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); 
    curl_setopt($ch, CURLOPT_POST, true);
    curl_setopt($ch, CURLOPT_POSTFIELDS, $data);

    $result = curl_exec($ch); 

    $status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    $hout   = curl_getinfo($ch, CURLINFO_HEADER_OUT);

    //echo "\n"; var_dump($hout); echo "\n"; 

    curl_close($ch); 

    return array('status'=>$status, 'result'=>$result);  
} 

如果我 var_dump($hout) 来自 do_curl 函数...实际发送的标头是:

POST /resfulness/post HTTP/1.1
Authorization: Basic dXNlclxuYW1lOnBhc3N3b3JkIQ==
Host: www.thingsandstuff.com:8080
Accept: */*
Content-Length: 409
Content-Type: application/x-www-form-urlencoded

<?xml version="1.0" encoding="UTF-8" ?>
        <entry xmlns="http://purl.org/atom/ns#"> 
            <xml data goes here>
                <ns:thing1>value1</ns:thing1>
                <ns:thing2>value2</ns:thing2>
            </xml data goes here>
        </entry>

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-03-25
    • 2011-11-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-02-01
    • 2013-06-21
    相关资源
    最近更新 更多