我正在嘗試爲使用Perl(或者XS模塊)編寫的Web服務器實現NTLM授權。我的理解是,它應該按以下方式工作:Perl中的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。
不幸的是我所有的努力來驗證NTLM令牌有兩種SEC_E_INVALID_TOKEN或SEC_E_INSUFFICIENT_MEMORY導致我建議我的NTLM令牌是不正確的失敗在AcceptSecurityContext。下面是一些幫助展示我的方法的代碼片段。
# 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
我也想知道如何做到這一點! –