我们相信:世界是美好的,你是我也是。平行空间的世界里面,不同版本的生活也在继续...

还是继续401状态码的授权认证问题,本文描述的是一个更加不常见的授权认证模式NTLM,具体来说,就是Net-NTLMv2。由于这个这个认证体系下,数据交换的实际过程比较复杂,所以本文中,并不会具体描述其原理,而是专注于其最简单的应用,以建立初步印象为主。

苏南大叔:php如何利用401状态码完成ntlm认证?Net-NTLMv2 - php-ntlmv2
php如何利用401状态码完成ntlm认证?Net-NTLMv2(图4-1)

苏南大叔的“程序如此灵动”博客,记录苏南大叔的编程经验文章。本文测试环境:win10nginx@1.15.11php@8.2.9ntschrome@121.0.6167.140internet explorer

关于ntlm.php

关于php下使用ntlm鉴权方式的文章,非常少。能找到的内容,都是使用了一款叫做ntlm.php的类库封装。由于ntlm这个认证方式,有着相对复杂的协议数据交换过程。所以,有国外友人对此过程进行了封装,使其变得简单化。作者对于其代码做了比较详细的描述,参考文章:

苏南大叔:php如何利用401状态码完成ntlm认证?Net-NTLMv2 - github-ntlm
php如何利用401状态码完成ntlm认证?Net-NTLMv2(图4-2)

代码下载地址:

php8下的困惑

mhash(MHASH_MD4,$s);

php8下,上述代码中所涉及的mhash()被废弃了,所以会有错误提示。

Deprecated: Function mhash() is deprecated

由于这个函数过于小众,所以即使是php官方文档也没有明确说明新的替代函数。不过,仔细多次阅读ntlm.php的文档及代码的话,就可以找到取代方案。

pack('H*', hash('md4', $s));

苏南大叔:php如何利用401状态码完成ntlm认证?Net-NTLMv2 - ntlm-md4
php如何利用401状态码完成ntlm认证?Net-NTLMv2(图4-3)

可运行demo

这个代码的绝大多数逻辑都是ntlm.php作者写的,这里仅仅是稍稍整理而已。

苏南大叔:php如何利用401状态码完成ntlm认证?Net-NTLMv2 - login-ui
php如何利用401状态码完成ntlm认证?Net-NTLMv2(图4-4)

完整可运行范例如下:

include 'ntlm.php';
function get_ntlm_user_hash($user)
{
    $userdb = array('admin' => 'password', 'guest' => 'guest');
    if (!isset($userdb[strtolower($user)])) {
        return false;
    }
    // return mhash(MHASH_MD4, ntlm_utf8_to_utf16le($userdb[strtolower($user)]));
    $s = ntlm_utf8_to_utf16le($userdb[strtolower($user)]);
    return pack('H*', hash('md4', $s));
}
session_start();
$auth = ntlm_prompt("testwebsite", "testdomain", "mycomputer", "testdomain.local", "mycomputer.local", "get_ntlm_user_hash");
// var_dump($auth);
if ($auth['authenticated']) {
    print "You are authenticated as $auth[username] from $auth[domain]/$auth[workstation]";
}

这里就预制两个合法的用户名密码,如下所示:

$userdb = array('admin' => 'password', 'guest' => 'guest');

相关文章

总结

ntlm的文章,本文仅仅是个抛砖引玉,更多内容留作后续描述。

如果本文对您有帮助,或者节约了您的时间,欢迎打赏瓶饮料,建立下友谊关系。
本博客不欢迎:各种镜像采集行为。请尊重原创文章内容,转载请保留作者链接。

 【福利】 腾讯云最新爆款活动!1核2G云服务器首年50元!

 【源码】本文代码片段及相关软件,请点此获取更多信息

 【绝密】秘籍文章入口,仅传授于有缘之人   php