前几天在问答区提了一下这个问题,所有回答问题的朋友都说不可能通过PHP实现,碰巧我的实习负责人帮我找到了一个方法,貌似是通过NTLM来实现的,我是新手,对具体原理也知之不详,只是自己测试了一下,很好用.
所以赶快拿出来与大家分享.这是一个法国人写的,所以编码中的注释都是法语,如果有朋友很想了解某行的注释含义,请回帖说明,我可以试着翻译一下.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
|
<?php
/***********************************************************************
************************************************************************
*
* PHP NTLM GET LOGIN
* Version 0.2.1
* Copyright (c) 2004 Nicolas GOLLET ( Nicolas (dot) gollet (at) secusquad (dot) com )
* Copyright (c) 2004 Flextronics Saint-Etienne
*
* This program is free software. You can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License.
*
***********************************************************************/
session_start();
$headers = apache_request_headers(); // 获取用户头
if (@ $_SERVER [ 'HTTP_VIA' ] != NULL){ // 确认是否使用了代理(proxy),因为ntlm验证不能穿过代理.
echo "Proxy bypass!" ;
}
elseif ( $headers [ 'Authorization' ] == NULL){ //si l'entete autorisation est inexistante如果许可头不存在
header( "HTTP/1.0 401 Unauthorized" ); //envoi au client le mode d'identification
header( "WWW-Authenticate: NTLM" ); //dans notre cas le NTLM
exit ; //on quitte
}
if (isset( $headers [ 'Authorization' ])) //dans le cas d'une authorisation (identification)
{
if ( substr ( $headers [ 'Authorization' ],0,5) == 'NTLM ' ){ // 确认client是否在ntlm下
$chaine = $headers [ 'Authorization' ];
$chaine = substr ( $chaine , 5); // 获取 base64-encoded type1 信息
$chained64 = base64_decode ( $chaine ); // 解码 base64 到 $chained64
if (ord( $chained64 {8}) == 1){
// |_ byte signifiant l'etape du processus d'identification (etape 3)
// verification du drapeau NTLM "0xb2" ?l'offset 13 dans le message type-1-message (comp ie 5.5+) :
if (ord( $chained64 [13]) != 178){
echo "NTLM Flag error!" ;
exit ;
}
$retAuth = "NTLMSSP" . chr (000). chr (002). chr (000). chr (000). chr (000). chr (000). chr (000). chr (000);
$retAuth .= chr (000). chr (040). chr (000). chr (000). chr (000). chr (001). chr (130). chr (000). chr (000);
$retAuth .= chr (000). chr (002). chr (002). chr (002). chr (000). chr (000). chr (000). chr (000). chr (000);
$retAuth .= chr (000). chr (000). chr (000). chr (000). chr (000). chr (000). chr (000);
$retAuth64 = base64_encode ( $retAuth ); // encode en base64
$retAuth64 = trim( $retAuth64 ); // enleve les espaces de debut et de fin
header( "HTTP/1.0 401 Unauthorized" ); // envoi le nouveau header
header( "WWW-Authenticate: NTLM $retAuth64" ); // avec l'identification suppl閙entaire
exit ;
}
else if (ord( $chained64 {8}) == 3){
// |_ byte signifiant l'etape du processus d'identification (etape 5)
// on recupere le domaine
$lenght_domain = (ord( $chained64 [31])*256 + ord( $chained64 [30])); // longueur du domain
$offset_domain = (ord( $chained64 [33])*256 + ord( $chained64 [32])); // position du domain.
$domain = str_replace ( "\0" , "" , substr ( $chained64 , $offset_domain , $lenght_domain )); // decoupage du du domain
//le login
$lenght_login = (ord( $chained64 [39])*256 + ord( $chained64 [38])); // longueur du login.
$offset_login = (ord( $chained64 [41])*256 + ord( $chained64 [40])); // position du login.
$login = str_replace ( "\0" , "" , substr ( $chained64 , $offset_login , $lenght_login )); // decoupage du login
if ( $login != NULL){
// stockage des donn閑s dans des variable de session
$_SESSION [ 'Login' ]= $login ;
header( "Location: newpage.php" );
exit ;
}
else {
echo "NT Login empty!" ;
}
}
}
}
?>
|