【问题标题】:Client part of the Digest Authentication using PHP POST to Web Service使用 PHP POST 到 Web 服务的摘要式身份验证的客户端部分
【发布时间】:2013-09-06 19:13:00
【问题描述】:

我正在尝试发布到 Web 服务(不是 RESTful)并通过 PHP 获得响应。但是,该 Web 服务需要摘要式身份验证。

我一直在网上搜索,发现大多数讨论和文章都是关于相反的方式(向用户请求摘要身份验证),而不是使用 PHP 响应它。

我可以使用该线程提供的代码生成摘要响应:HTTP Digest authenticating in PHP,但问题是与(或不?)POST 数据一起发送它。

这是我正在使用的代码:

$domain = "https://api.example.com";
$uri = "/ws.asmx/do";

// get headers
$response1_array = get_headers($web_service_url);
// get request part of digest auth
$response1 = $response1_array[5];
// get things behind "WWW-Authenticate:"
$response1 = substr($response1, 18);

// response() is a invented function to calculate the response according to the RFC2617
$response2 = response($response1, "username", "password", "GET", $uri);

// manually add some headers for POST, and fill out the parts that the calculation function missed
// for auth
$header =  
        "Host: api.example.com\r\n" .
        "Content-Type: application/x-www-form-urlencoded\r\n" .
        "Authorization: " . $response2 . ", nc=\"00000001\", opaque=\"0000000000000000\"" . "\r\nContent-Length: 0\r\n\r\n";

// echo the response from server
echo do_post_request($web_service_url, "", $header);

function do_post_request($url, $data, $optional_headers = null)
{
  $params = array('http' => array(
              'method' => 'POST',
              'content' => $data
            ));
  if ($optional_headers !== null) {
    $params['http']['header'] = $optional_headers;
  }
  $ctx = stream_context_create($params);

  $fp = fopen($url, 'rb', false, $ctx);

  if (!$fp) {
    throw new Exception("Problem with $url");
  }
  $response = stream_get_contents($fp);
  if ($response === false) {
    throw new Exception("Problem reading data from $url");
  }
  return $response;
}

在回复中:

$response1(from web service):
    Digest realm="example.com", nonce="OS82LzIwMTMgMTI6MDI6NDYgUE0", opaque="0000000000000000", stale=false, algorithm=MD5, qop="auth"

$response2(I calculated given the server response):
    Digest username="username", realm="example.com", nonce="OS82LzIwMTMgMTI6MDI6NDYgUE0", uri="/ws.asmx/do", cnonce="1378494106", nc="1", response="0f96788854cf2098ba22c6121529d7de", qop="auth"

the final (2nd) response from server:
    Warning: fopen(https://api.example.com/ws.asmx/do): failed to open stream: HTTP request failed! HTTP/1.1 500 Internal Server Error in ...

我不明白为什么在这种情况下服务器会响应 500 错误。代码有什么问题吗?或者有没有人遇到过这个问题并解决了它并可以帮助我解决问题?

问候,

米洛

【问题讨论】:

    标签: php digest-authentication


    【解决方案1】:

    经过 2 天的摸索,最终用 cURL 解决了这个问题。我想这是第一次发布一段现成的用于摘要身份验证的 PHP 代码,希望它可以帮助和我在同一个沟里的人。

    代码:

    <?php
    
    error_reporting(E_ALL); 
    ini_set( 'display_errors','1');
    
    $url = "https://api.example.com/ws.asmx/do";
    $username = "username";
    $password = "pwd";
    $post_data = array(
            'fieldname1' => 'value1',
            'fieldname2' => 'value2'
      );
    
    $options = array(
            CURLOPT_URL            => $url,
            CURLOPT_HEADER         => true,    
            CURLOPT_VERBOSE        => true,
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_FOLLOWLOCATION => true,
            CURLOPT_SSL_VERIFYPEER => false,    // for https
            CURLOPT_USERPWD        => $username . ":" . $password,
            CURLOPT_HTTPAUTH       => CURLAUTH_DIGEST,
            CURLOPT_POST           => true,
            CURLOPT_POSTFIELDS     => http_build_query($post_data) 
    );
    
    $ch = curl_init();
    
    curl_setopt_array( $ch, $options );
    
    try {
      $raw_response  = curl_exec( $ch );
    
      // validate CURL status
      if(curl_errno($ch))
          throw new Exception(curl_error($ch), 500);
    
      // validate HTTP status code (user/password credential issues)
      $status_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
      if ($status_code != 200)
          throw new Exception("Response with Status Code [" . $status_code . "].", 500);
    
    } catch(Exception $ex) {
        if ($ch != null) curl_close($ch);
        throw new Exception($ex);
    }
    
    if ($ch != null) curl_close($ch);
    
    echo "raw response: " . $raw_response; 
    
    ?>
    

    【讨论】:

      【解决方案2】:

      如果你想用 PUT 方法发送 JSON 数据:

      <?php
      
      error_reporting(E_ALL); 
      ini_set( 'display_errors','1');
      
      $url = "https://api.example.com/ws.asmx/do";
      $username = "username";
      $password = "pwd";
      $post_data = array(
              'fieldname1' => 'value1',
              'fieldname2' => 'value2'
        );
      
      $options = array(
              CURLOPT_URL            => $url,
              CURLOPT_HEADER         => true,    
              CURLOPT_VERBOSE        => true,
              CURLOPT_RETURNTRANSFER => true,
              CURLOPT_FOLLOWLOCATION => true,
              CURLOPT_SSL_VERIFYPEER => false,    // for https
              CURLOPT_USERPWD        => $username . ":" . $password,
              CURLOPT_HTTPAUTH       => CURLAUTH_DIGEST,
              CURLOPT_CUSTOMREQUEST  => "PUT",
              CURLOPT_POSTFIELDS     => json_encode($post_data) ,
      );
      
      $ch = curl_init();
      
      curl_setopt_array( $ch, $options );
      
      try {
        $raw_response  = curl_exec( $ch );
      
        // validate CURL status
        if(curl_errno($ch))
            throw new Exception(curl_error($ch), 500);
      
        // validate HTTP status code (user/password credential issues)
        $status_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
        if ($status_code != 200)
            throw new Exception("Response with Status Code [" . $status_code . "].", 500);
      
      } catch(Exception $ex) {
          if ($ch != null) curl_close($ch);
          throw new Exception($ex);
      }
      
      if ($ch != null) curl_close($ch);
      
      echo "raw response: " . $raw_response; 
      
      ?>
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2023-03-16
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-02-19
        • 2017-02-16
        相关资源
        最近更新 更多