前几天在问答区提了一下这个问题,所有回答问题的朋友都说不可能通过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!" ; } } } } ?> |