Perl中的NTLM授权

 阳光下微醺的我 发布于 2023-01-19 16:44

我正在尝试为用Perl(或者可能是XS模块)编写的Web服务器实现NTLM授权.我的理解是它应该以下列方式工作:

c -> s: GET
s -> c: 401, WWW-Authenticate: NTLM
c -> s: GET, Authorization: NTLM [Type1 Message]
s -> c: 401, WWW-Authenticate: NTLM [Type2 Message]
c -> s: GET, Authorization: NTLM [Type3 Message]

IF s.Check([Type3 Message]):
  s -> c: 200
ELSE:
  s -> c: 401

为了生成Type3消息,我使用了Authen :: Perl :: NTLM和Authen :: NTLM :: HTTP,这两者似乎都可以完美地生成消息,但是,它们没有提供检查Type3消息的功能.

我的下一步是尝试使用Win32 :: IntAuth来验证NTLM令牌.是我遇到麻烦的地方,开发人员和搜索到的其他信息片段说这个模块应该能够验证NTLM二进制令牌.

该模块包含一些Win32 API调用,即AcquireCredntialsHandle,AcceptSecurityContext,CompleteAuthToken和ImpersonateSecurityContext.

不幸的是,我在AcceptSecurityContext上验证NTLM令牌的所有尝试都失败了,SEC_E_INVALID_TOKENSEC_E_INSUFFICIENT_MEMORY导致我建议我的NTLM令牌不正确.下面是一些代码片段,以帮助显示我的方法.

# other code
...
if (not defined $headers->header('Authorization')) {
    initHandshake($response); 
} else { 
    my $authHeader = $headers->header('Authorization');
    if ($authHeader =~ m/^NTLM\s(.+)$/i) { 
        my $message = $1;
        if (length($message) == 56) {
            handleType1($response, $message);
        } else {
            handleType3($response, $message);
        }
    } else {
        printf "ERROR - Unable to pull out an NTLM message.\n";
        print $authHeader . "\n";
    }
} 
... 
sub handleType3 {
    my $response = shift();
    my $message = shift();
    print "handleType3 - ", $message, "\n";
    my $auth = Win32::IntAuth->new(debug => 1);
    my $token = $auth->get_token_upn(decode_base64($message)) or die 
                           "Couldn'timpersonate user, ", $auth->last_err_txt();
    print "Hurrargh. User ", $auth->get_username(), " authed!\n";
    $response->status(200);
} 
..

完整的代码可以在这里查看:http://codepad.org/cpMWnFru

撰写答案
今天,你开发时遇到什么问题呢?
立即提问
热门标签
PHP1.CN | 中国最专业的PHP中文社区 | PNG素材下载 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有