C# 和 php 中的 NTLM 请求
NTLM request in C# and php
我在 C# 中有一个 ntlm 请求可以正常工作,在 php 中有相同的请求可以连接,但是 returns 响应中有一个错误。
这是 C# 代码:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.IO;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
var httpWebRequest = (HttpWebRequest)WebRequest.Create("http://example.com/Query/ExecuteReportView");
httpWebRequest.ContentType = "text/json";
httpWebRequest.Method = "POST";
httpWebRequest.UseDefaultCredentials = false;
httpWebRequest.PreAuthenticate = true;
var c = new NetworkCredential("username", "password", "domain");
CredentialCache credentialCache = new CredentialCache();
credentialCache.Add(new Uri("http://example.com"), "NTLM", c);
httpWebRequest.Credentials = credentialCache;
using (var streamWriter = new StreamWriter(httpWebRequest.GetRequestStream()))
{
string json = "{\"SysName\":\"Callbacks\"," +
"\"SysCategory\":\"Eai.CCM.Model.FolderView\"," +
"\"StartIndex\":0," +
"\"PageLength\":10}";
streamWriter.Write(json);
streamWriter.Flush();
streamWriter.Close();
}
var httpResponse = (HttpWebResponse)httpWebRequest.GetResponse();
using (var streamReader = new StreamReader(httpResponse.GetResponseStream()))
{
var result = streamReader.ReadToEnd();
Console.Out.WriteLine(result);
}
Console.ReadLine();
}
}
}
有效,并且 returns 是预期的 json 字符串。
这是我尝试在 php 中做同样的事情:
<?php
$data = array
(
"SysName" => "Callbacks",
"SysCategory" => "Eai.CCM.Model.FolderView",
"StartIndex" => 0,
"PageLength" => 10
);
$body = json_encode($data);
$headers = array(
"Transfer-Encoding: chunked",
"Content-Type: application/json"
);
$ch = curl_init();
curl_setopt($ch, CURLOPT_USERPWD, 'username:password');
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
curl_setopt($ch, CURLOPT_URL, 'example.com/Query/ExecuteReportView');
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_NTLM);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($ch, CURLINFO_HEADER_OUT, true);
curl_setopt($ch, CURLOPT_FAILONERROR, 0);
curl_setopt($ch, CURLOPT_MAXREDIRS, 100);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_POSTFIELDS, dechex(strlen($body)) . "\r\n" . $body . "\r\n");
curl_exec($ch);
curl_close($ch);
?>
一个显着差异是 php 代码使用分块编码,因为内容长度方法不断给我一个错误,告诉我需要指定内容长度或分块发送数据。
在我的 php 脚本中,是否有任何明显突出的东西被我遗漏了?
php 脚本连接并返回响应,所以我显然没有给它正确的信息(因为我在 c# 版本中)。
这就是 php 版本 returns:
{"$id":"1","Message":"An error has occurred.","ExceptionMessage":"Object reference not set to an instance of an object.","ExceptionType":"System.Exception","StackTrace":null}
我正在使用 php 5.6.6.
编辑:
我的 php 脚本在 php 5.2.17 中使用内容长度而不是分块编码数据
在 php 5.5.21
中有同样的问题
phpinfo 为 5.2.17 提供以下信息:
cURL support enabled
cURL Information libcurl/7.21.0 OpenSSL/0.9.8q zlib/1.2.3
以及以下 5.6.6
cURL support enabled
cURL Information 7.40.0
Age 3
Features
AsynchDNS Yes
CharConv No
Debug No
GSS-Negotiate No
IDN Yes
IPv6 Yes
krb4 No
Largefile Yes
libz Yes
NTLM Yes
NTLMWB No
SPNEGO Yes
SSL Yes
SSPI Yes
TLS-SRP No
Protocols dict, file, ftp, ftps, gopher, http, https, imap, imaps, ldap, pop3, pop3s, rtsp, scp, sftp, smtp, smtps, telnet, tftp
Host i386-pc-win32
SSL Version OpenSSL/1.0.1k
ZLib Version 1.2.7.3
libSSH Version libssh2/1.4.3
终于得到答案:
似乎 IIS 正在为我做一些事情。似乎发送 header "Transfer-Encoding: chunked" 告诉 IIS 为我做分块。所以我不需要自己分块数据。
<?php
$data = array
(
"SysName" => "Callbacks",
"SysCategory" => "Eai.CCM.Model.FolderView",
"StartIndex" => 0,
"PageLength" => 10
);
$body = json_encode($data);
$headers = array(
"Transfer-Encoding: chunked",
'Content-Type: application/json'
);
$ch = curl_init();
curl_setopt($ch, CURLOPT_USERPWD, 'username:password');
curl_setopt($ch, CURLOPT_URL, 'example.com/Query/ExecuteReportView');
curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_NTLM);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_POSTFIELDS, $body);
curl_exec($ch);
curl_close($ch);
?>
我在 C# 中有一个 ntlm 请求可以正常工作,在 php 中有相同的请求可以连接,但是 returns 响应中有一个错误。
这是 C# 代码:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.IO;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
var httpWebRequest = (HttpWebRequest)WebRequest.Create("http://example.com/Query/ExecuteReportView");
httpWebRequest.ContentType = "text/json";
httpWebRequest.Method = "POST";
httpWebRequest.UseDefaultCredentials = false;
httpWebRequest.PreAuthenticate = true;
var c = new NetworkCredential("username", "password", "domain");
CredentialCache credentialCache = new CredentialCache();
credentialCache.Add(new Uri("http://example.com"), "NTLM", c);
httpWebRequest.Credentials = credentialCache;
using (var streamWriter = new StreamWriter(httpWebRequest.GetRequestStream()))
{
string json = "{\"SysName\":\"Callbacks\"," +
"\"SysCategory\":\"Eai.CCM.Model.FolderView\"," +
"\"StartIndex\":0," +
"\"PageLength\":10}";
streamWriter.Write(json);
streamWriter.Flush();
streamWriter.Close();
}
var httpResponse = (HttpWebResponse)httpWebRequest.GetResponse();
using (var streamReader = new StreamReader(httpResponse.GetResponseStream()))
{
var result = streamReader.ReadToEnd();
Console.Out.WriteLine(result);
}
Console.ReadLine();
}
}
}
有效,并且 returns 是预期的 json 字符串。
这是我尝试在 php 中做同样的事情:
<?php
$data = array
(
"SysName" => "Callbacks",
"SysCategory" => "Eai.CCM.Model.FolderView",
"StartIndex" => 0,
"PageLength" => 10
);
$body = json_encode($data);
$headers = array(
"Transfer-Encoding: chunked",
"Content-Type: application/json"
);
$ch = curl_init();
curl_setopt($ch, CURLOPT_USERPWD, 'username:password');
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
curl_setopt($ch, CURLOPT_URL, 'example.com/Query/ExecuteReportView');
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_NTLM);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($ch, CURLINFO_HEADER_OUT, true);
curl_setopt($ch, CURLOPT_FAILONERROR, 0);
curl_setopt($ch, CURLOPT_MAXREDIRS, 100);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_POSTFIELDS, dechex(strlen($body)) . "\r\n" . $body . "\r\n");
curl_exec($ch);
curl_close($ch);
?>
一个显着差异是 php 代码使用分块编码,因为内容长度方法不断给我一个错误,告诉我需要指定内容长度或分块发送数据。
在我的 php 脚本中,是否有任何明显突出的东西被我遗漏了?
php 脚本连接并返回响应,所以我显然没有给它正确的信息(因为我在 c# 版本中)。
这就是 php 版本 returns:
{"$id":"1","Message":"An error has occurred.","ExceptionMessage":"Object reference not set to an instance of an object.","ExceptionType":"System.Exception","StackTrace":null}
我正在使用 php 5.6.6.
编辑:
我的 php 脚本在 php 5.2.17 中使用内容长度而不是分块编码数据
在 php 5.5.21
中有同样的问题phpinfo 为 5.2.17 提供以下信息:
cURL support enabled
cURL Information libcurl/7.21.0 OpenSSL/0.9.8q zlib/1.2.3
以及以下 5.6.6
cURL support enabled
cURL Information 7.40.0
Age 3
Features
AsynchDNS Yes
CharConv No
Debug No
GSS-Negotiate No
IDN Yes
IPv6 Yes
krb4 No
Largefile Yes
libz Yes
NTLM Yes
NTLMWB No
SPNEGO Yes
SSL Yes
SSPI Yes
TLS-SRP No
Protocols dict, file, ftp, ftps, gopher, http, https, imap, imaps, ldap, pop3, pop3s, rtsp, scp, sftp, smtp, smtps, telnet, tftp
Host i386-pc-win32
SSL Version OpenSSL/1.0.1k
ZLib Version 1.2.7.3
libSSH Version libssh2/1.4.3
终于得到答案:
似乎 IIS 正在为我做一些事情。似乎发送 header "Transfer-Encoding: chunked" 告诉 IIS 为我做分块。所以我不需要自己分块数据。
<?php
$data = array
(
"SysName" => "Callbacks",
"SysCategory" => "Eai.CCM.Model.FolderView",
"StartIndex" => 0,
"PageLength" => 10
);
$body = json_encode($data);
$headers = array(
"Transfer-Encoding: chunked",
'Content-Type: application/json'
);
$ch = curl_init();
curl_setopt($ch, CURLOPT_USERPWD, 'username:password');
curl_setopt($ch, CURLOPT_URL, 'example.com/Query/ExecuteReportView');
curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_NTLM);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_POSTFIELDS, $body);
curl_exec($ch);
curl_close($ch);
?>