PHP NTLM身份验证+soap客户端

2023-12-22

我遇到了一个需要实现受 NTLM 身份验证保护的 Web 服务的项目。

我通过 PHP 尝试过SoapClient:

$client = new \SoapClient("http://hostname.com/webservice",
            array(
                'cache_wsdl' => WSDL_CACHE_NONE,
                'login' => "username",
                'password' => "password"
            ));

这会引发此错误:

PHP 致命错误:SOAP-错误:正在解析 WSDL:无法加载 'http://hostname.com/webservice http://hostname.com/webservice' : 加载外部实体失败 ”http://hostname.com/webservice http://hostname.com/webservice"

我通过 CURL 尝试了一下:

curl --ntlm -u username:password "http://hostname.com/webservice" --verbose

它按预期工作并返回正确的 xml。

但再一次SoapClient不支持 NTLM 身份验证。

有人知道 PHP Soap+NTLM 吗?

提前致谢


我最近也遇到了这个问题。

这是我找到的解决方案:

Create NTLMStream.php包含以下内容:

<?php
/*
* Original https://thomas.rabaix.net/blog/2008/03/using-soap-php-with-ntlm-authentication
* Modified by http://blogs.msdn.com/b/freddyk/archive/2010/01/19/connecting-to-nav-web-services-from-php.aspx:
*/

class NTLMStream
{
    private $path;
    private $mode;
    private $options;
    private $opened_path;
    private $buffer;
    private $pos;
    
    public function stream_open($path, $mode, $options, $opened_path) {
        $this->path = $path;
        $this->mode = $mode;
        $this->options = $options;
        $this->opened_path = $opened_path;
        $this->createBuffer($path);
        return true;
    }
    public function stream_close() {
        curl_close($this->ch);
    }
    public function stream_read($count) {
        if(strlen($this->buffer) == 0) {
            return false;
        }
        $read = substr($this->buffer,$this->pos, $count);
        $this->pos += $count;
        return $read;
    }
    public function stream_write($data) {
        if(strlen($this->buffer) == 0) {
            return false;
        }
        return true;
    }
    public function stream_eof() {
        return ($this->pos > strlen($this->buffer));
    }
    public function stream_tell() {
        return $this->pos;
    }
    public function stream_flush() {
        $this->buffer = null;
        $this->pos = null;
    }
    public function stream_stat() {
        $this->createBuffer($this->path);
        $stat = array(
            'size' => strlen($this->buffer),
        );
        return $stat;
    }
    public function url_stat($path, $flags) {
        $this->createBuffer($path);
        $stat = array(
            'size' => strlen($this->buffer),
        );
        return $stat;
    }
    private function createBuffer($path) {
        if($this->buffer) {
            return;
        }
        $this->ch = curl_init($path);
        curl_setopt($this->ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($this->ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
        curl_setopt($this->ch, CURLOPT_HTTPAUTH, CURLAUTH_NTLM);
        curl_setopt($this->ch, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($this->ch, CURLOPT_USERPWD, USERPWD);
        $this->buffer = curl_exec($this->ch);
        $this->pos = 0;
    }
}

class NTLMSoapClient extends \SoapClient
{
    function __doRequest($request, $location, $action, $version, $one_way = 0) {
        $headers = array(
            'Method: POST',
            'Connection: Keep-Alive',
            'User-Agent: PHP-SOAP-CURL',
            'Content-Type: text/xml; charset=utf-8',
            'SOAPAction: "'.$action.'"',
        );
        $this->__last_request_headers = $headers;
        $ch = curl_init($location);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
        curl_setopt($ch, CURLOPT_POST, true );
        curl_setopt($ch, CURLOPT_POSTFIELDS, $request);
        curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
        curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_NTLM);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($ch, CURLOPT_USERPWD, USERPWD);
        $response = curl_exec($ch);
        return $response;
    }
    function __getLastRequestHeaders() {
        return implode("\n", $this->__last_request_headers)."\n";
    }
}

然后在你的test.php

<?php
define('USERPWD', 'domain\username:password');
require_once("NTLMStream.php");
stream_wrapper_unregister("https");
stream_wrapper_register("https", "NTLMStream");
$params = [
    'stream_context' => stream_context_create([
           'ssl' => [
            'ciphers'=>'RC4-SHA', 
            'verify_peer'=>false, 
            'verify_peer_name'=>false, 
            'allow_self_signed'=>true,
        ]]),
    'cache_wsdl' => WSDL_CACHE_NONE,
    'soap_version' => SOAP_1_1,
    'trace' => 1,
    'connection_timeout' => 180, 
    'features' => SOAP_SINGLE_ELEMENT_ARRAYS
];
$client = new NTLMSoapClient("https://hostname.com/webservice", $params);
$retVal = $client->ReadMultiple(...
...

对于 http:// 而不是 https:// 替换:

stream_wrapper_register("http", "NTLMStream")
stream_wrapper_register("https", "NTLMStream")
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

PHP NTLM身份验证+soap客户端 的相关文章

随机推荐

  • 在全球范围内使用 reCAPTCHA

    我正在尝试按照以下网址中的说明在全球范围内使用 reCAPTCHAhttps developers google com recaptcha docs faq can i use recaptcha globally https devel
  • Log4Net RollingFileAppender 生成重复日志

    我有一个在单个服务器上运行的 WCF 服务 使用 Log4net 通过 INFO 和 WARN 级别日志条目跟踪使用情况 使用具有以下非常标准配置的 RollingFileAppender
  • 使用 FileUpload 控件一次将多个图像保存到数据库

    我正在一家公司博客网站上工作 当用户发布帖子时 他们可以将计算机中的图像添加到帖子中 我使用 FileUpload 控件来执行此操作 效果很好 但是 我正在尝试更改功能以允许用户在一篇文章中选择和上传多个图像 但我遇到了一些问题 我已将 允
  • ASP.NET MVC5 每个 Razor 页面首次加载时非常慢

    这与以下情况下的延迟体验不同 第一个请求到达 但这是每次第一次访问基于 Razor 的视图时都会遇到的延迟 可能需要一两秒 对该视图的所有后续请求都非常快 即使对于不执行任何类型的编程工作 例如访问数据库等 的简单视图 也会发生这种情况 我
  • 在添加另一个视图之前检查布局膨胀器中是否存在视图

    在我的 android 项目中 我动态地将表单添加到我的线性布局中 然后在使用按钮完成后销毁它们 但是 当我单击 添加按钮 时 它会无限添加更多表单 尽管我一次只想要一个 我如何检查我的 LinearLayout 帐户 是否已添加到视图中或
  • Elasticsearch / lucene 高亮

    我正在使用 ElasticSearch 来索引文档 我的映射是 mongodocid boost 1 0 store yes type string fulltext boost 1 0 index analyzed store yes t
  • ListBox 中的“Items.Clear()”后“SelectedIndexChanged”未触发

    对于列表框 选择模式设置为 一 我希望跟踪是否有选定的项目或没有选定的项目 为此 我订阅了 SelectedIndexChanged 的 方法并检查 SelectedIndex 是否为 1 但是 我注意到调用 Items Clear 后该事
  • 在 ExtJS 中突出显示/选择网格行

    我是 Ext JS 的新手 我正在开发一个网格面板 当我选择 单击任何行时 与所选行相关的某些数据将显示在网格下方的面板中 此外 当加载窗口时 默认情况下应选择 突出显示第一个窗口 目前网格和面板已正确显示 即使与所选行相关的数据也会显示在
  • Angular2 FileSaver.js

    我将 FileSaver js 与 Angular 2 一起使用 效果很好 但是 我在构建中遇到语义错误 错误 TS2304 找不到名称 saveAs 我正在使用 Angular 2 种子并将库添加到我的 project config 中
  • Apache Ivy:本地ivy缓存和本地存储库之间的区别

    默认情况下 ivy 在你的目录下安装了一个 本地缓存
  • iOS是静态框架还是动态框架?

    这可能听起来像一个愚蠢的问题 但如果您有第三方 Party framework 文件 您能判断它是静态还是动态吗 我的意思是 如果你往里面看 它们看起来有什么不同吗 两者都可以 然而 只有 iOS8 才允许应用程序包中使用动态框架 找出答案
  • WPF DependencyObject 调用线程异常

    我有以下代码 它创建一个临时文件夹 并使用 FileSystemWatcher 轮询添加到 Location 属性上的文件夹中的文件 并将它们添加到列表中 Pastebin 上的 Scratchdisk cs http pastebin c
  • Javascript 动态创建函数列表

    我有一块JavaScript我想要创建函数列表的代码 所有的函数都会被放入字典中d d a 会给我这个功能function console log a and d b 会给我这个功能function console log b 等等 这是我
  • 图灵机的时间复杂度和空间复杂度

    我认为图灵机的时间复杂度和空间复杂度的定义是相同的 我无法区分 它们之间 请帮我 谢谢 对于图灵机 时间复杂度是当机器根据某些输入启动时磁带移动的次数的度量 空间复杂度是指机器运行时写入磁带的单元数 The time complexity
  • 获取 Adob​​e Air 中的当前操作系统

    我正在使用 Adob e Flex Air 制作一个应用程序 我想知道是否有任何方法可以获取 Air 应用程序运行的操作系统 Use 能力 http livedocs adobe com flex 3 langref flash syste
  • “活动(调试)”与“调试”

    Visual Studio 调试器 C 调试配置的项目设置 视觉工作室2010 http msdn microsoft com en us library 2kf0yb05 aspx 视觉工作室2008 http msdn microsof
  • 为什么我的 Spring ContextRefreshedevent 被调用两次?

    我注册了一个 Spring ApplicationListener bean 来侦听 ContextRefreshed 事件 但出于某种奇怪的原因 我得到two致电onApplicationEvent ContextRefreshedEve
  • 如何确定一个数字中的所有设置位是否也在另一个数字中设置?

    给定 2 个二进制字符串a and b相同长度 例如111000 and 110000 是否可以检查是否所有设置位b也设置在a使用按位运算 在上面的例子中 b 110000在位置 1 和 2 从左到右 有两个设置位 这些位也设置在a 111
  • 计算价格并显示在 WooCommerce 产品单页上的价格下(简单价格、可变价格)

    我计划在我的 WooCommerce 产品页面上显示所有产品的新价格 这是每月的分期付款价格 我需要以低于正常价格 可变价格和简单价格 的价格显示此内容 如下所示 0 利息分期付款 3 093 卢比起 其中 3 093 卢比是新价格 这是我
  • PHP NTLM身份验证+soap客户端

    我遇到了一个需要实现受 NTLM 身份验证保护的 Web 服务的项目 我通过 PHP 尝试过SoapClient client new SoapClient http hostname com webservice array cache