LoginSignup
3
0

More than 3 years have passed since last update.

PHPのGuzzileクライアントでNTLM認証を超える

Last updated at Posted at 2019-06-02

会社のイントラサービスがNTLM認証とやらで守られていて、いろいろ調べたところのメモ

NTLMとは

この辺参照。ちと難しい
https://www.innovation.ch/personal/ronald/ntlm.html

Windowsにログインしているユーザ情報で、Webのアクセスの認可・認証をする感じでしょうか。Windowsにログインしている端末からだとユーザ認証を求められず(何も意識せずに)ブラウザでアクセスできるけど、プログラムから接続すると拒否されるような場合は、この環境かもしれません。

ちなみにProxyとは別の話です。外に通信するために特殊な認証をクリアしないといけない場合は、Cntlmを使ってNTLMv2認証Proxy環境をやっつけるを参照。

結論

Guzzile なら簡単だった(ちゃんとマニュアルを読めば解決)
https://guzzle3.readthedocs.io/http-client/client.html#auth

検証

とりあえず普通につなげてみる

test.php
$guzzile = new \GuzzleHttp\Client();

$option = ['verify' => false,];
$option['debug']=true;
$option['http_errors']=false;

$url = 'http://local-service...';

$response = $guzzile->get($url, $option);
$body = $response->getBody();
$data = (String)$body;
echo $data;

通信ログ(の一部)

*   Trying x.x.x.x...
* TCP_NODELAY set
* Connected to xx.xx.com (x.x.x.x) port 80 (#0)
> GET / HTTP/1.1
Host: xx.xx.com
User-Agent: GuzzleHttp/6.2.1 curl/7.54.1 PHP/7.0.21

< HTTP/1.1 401 Unauthorized
< Content-Type: text/plain; charset=utf-8
< Server: Microsoft-IIS/8.5
< SPRequestGuid: 
< request-id: 
< X-FRAME-OPTIONS: SAMEORIGIN
< SPRequestDuration: 2
< SPIisLatency: 0
< WWW-Authenticate: NTLM
< X-Powered-By: ASP.NET
< MicrosoftSharePointTeamServices: 
< X-Content-Type-Options: nosniff
< X-MS-InvokeApp: 1; RequireReadOnly
< Date: Sun, 02 Jun 2019 06:15:15 GMT
< Content-Length: 16
<
* Connection #0 to host xx.xx.com left intact
401 UNAUTHORIZED

結果は、401 UNAUTHORIZED が返ってくる。認証が必要だということですね。残念。この通信にWWW-Authenticate: NTLMが入っているのがヒントですね。NTLM認証下で動いているということですね。

オプションを追加する

Guzzileのauthをオプションを追加します。コードの修正は1行追加するだけなので簡単です。authオプションの3番目のオプションがあるのですね。

$guzzile = new \GuzzleHttp\Client();

$option = ['verify' => false,];
$option['debug']=true;
$option['http_errors']=false;

//↓ココ追加
$option['auth'] = ['user', 'password','ntlm'];

$url = 'http://local-service...';

$response = $guzzile->get($url, $option);
$body = $response->getBody();
$data = (String)$body;
echo $data;

通信ログ

*   Trying x.x.x.x...
* TCP_NODELAY set
* Connected to xx.xx.com (x.x.x.x) port 80 (#0)
* Server auth using NTLM with user '<USER>'
> GET /index.html HTTP/1.1
Host: xx.xx.com
Authorization: NTLM TlRMTVNTUAAxxx==
User-Agent: GuzzleHttp/6.2.1 curl/7.54.1 PHP/7.0.21

< HTTP/1.1 401 Unauthorized
< Server: Microsoft-IIS/8.5
< WWW-Authenticate: NTLM TlRMTVNTUAAxxxxxxxxxx=
< SPRequestGuid: 
< request-id: 
< X-FRAME-OPTIONS: SAMEORIGIN
< SPRequestDuration: 1
< SPIisLatency: 0
< X-Powered-By: ASP.NET
< MicrosoftSharePointTeamServices: 15.0.0.4569
< X-Content-Type-Options: nosniff
< X-MS-InvokeApp: 1; RequireReadOnly
< Date: Sun, 02 Jun 2019 11:30:03 GMT
< Content-Length: 0
<
* Connection #0 to host xx.xx.com left intact
* Issue another request to this URL: 'http://xx.xx.com/'
* Found bundle for host xx.xx.com: 0x15025758 [can pipeline]
* Re-using existing connection! (#0) with host xx.xx.com
* Connected to xx.xx.com (x.x.x.x) port 80 (#0)
* Server auth using NTLM with user '<USER>'
> GET /index.html HTTP/1.1
Host: xx.xx.com
Authorization: NTLM TlRMTVNTUAAxxxxxxxxxx=
User-Agent: GuzzleHttp/6.2.1 curl/7.54.1 PHP/7.0.21

< HTTP/1.1 200 OK
< Cache-Control: private, max-age=0
< Content-Type: text/html; charset=utf-8
< Expires: Sat, 18 May 2019 11:30:03 GMT
< Last-Modified: Sun, 02 Jun 2019 11:30:03 GMT
< Server: Microsoft-IIS/8.5
< X-SharePointHealthScore: 0
< X-AspNet-Version: 4.0.30319
< Set-Cookie: 
< Set-Cookie: 
< Set-Cookie: 
< SPRequestGuid: 0fa2e29e-1880-7002-7a3b-08c82a909236
< request-id: 0fa2e29e-1880-7002-7a3b-08c82a909236
< X-FRAME-OPTIONS: SAMEORIGIN
< SPRequestDuration: 453
< SPIisLatency: 0
< Persistent-Auth: true
< X-Powered-By: ASP.NET
< MicrosoftSharePointTeamServices: 15.0.0.4569
< X-Content-Type-Options: nosniff
< X-MS-InvokeApp: 1; RequireReadOnly
< Date: Sun, 02 Jun 2019 11:30:03 GMT
< Content-Length: 95613
<
* Connection #0 to host xx.xx.com left intact

<!DOCTYPE html >
以下、HTMLなので省略

無事にHTMLが取れました。

もうちょっと細かく見てみる

IDとパスワードを渡して通信すると、Guzzileによって自動的に2回の通信が行われます。

1回目の通信で、AuthorizationヘッダーがGuzzileによって付与されます。

> GET /index.html HTTP/1.1
Host: xx.xx.com
Authorization: NTLM TlRMTVNTUAAxxx==

そうすると、サーバーからWWW-Authenticateヘッダーが返ってきます。

< HTTP/1.1 401 Unauthorized
< Server: Microsoft-IIS/8.5
< WWW-Authenticate: NTLM TlRMTVNTUAAxxxxxxxxxx=

2回目の通信は、1回目の通信のレスポンスヘッダーの値をAuthorizationとしてに渡します。

> GET /index.html HTTP/1.1
Host: xx.xx.com
Authorization: NTLM TlRMTVNTUAAxxxxxxxxxx=

そうすると、無事、欲しかったコンテンツが返ってきます。

3
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
0