Phalcon で Digest 認証
ここでは Plugin として実装して追加された場合に全てのページに対して Digest 認証が必要なようになる実装としている.
特定のページのみなどは beforeDispatch() の最初あたりでアクション名などをチェックして認証が必要ないページならば true を返すなどするとよいと思う.
<?php
use Phalcon\Events\Event;
use Phalcon\Mvc\Dispatcher;
use Phalcon\Mvc\User\Plugin;
class Digest extends Plugin
{
private $realm = 'Restricted area';
private $users = ['nise_nabe' => 'password'];
public function beforeDispatch(Event $event, Dispatcher $dispatcher)
{
$data = $this->request->getDigestAuth();
if (empty($data)) {
$this->response->setStatusCode(401, 'Unauthorized');
$header ='Digest realm="'.$this->realm.'",qop="auth",nonce="'.uniqid().'",opaque="'.md5($this->realm).',algorithm=MD5';
$this->response->setHeader('WWW-Authenticate', $header);
$this->response->send();
return false;
} else {
$H1 = md5($data['username'].':'.$this->realm.':'.$this->users[$data['username']]);
$H2 = md5($this->request->getMethod().':'.$data['uri']);
$valid_response = md5(implode(':', [$H1, $data['nonce'], $data['nc'], $data['cnonce'], $data['qop'], $H2]));
if ($data['response'] !== $valid_response) {
$this->response->setStatusCode(401, 'Unauthorized');
$this->response->send();
return false;
}
}
}
}
動作確認
上記コードを dispatcher に登録していると下記のような動作になるはず.(追加方法例)
正しいユーザとパスワード(password)
$ curl -s -I http://localhost/ --digest --user nise_nabe | grep HTTP
Enter host password for user 'nise_nabe':
HTTP/1.1 401 Unauthorized
HTTP/1.1 200 OK
正しいユーザと間違ったパスワード
$ curl -s -I http://localhost/ --digest --user nise_nabe | grep HTTP
Enter host password for user 'nise_nabe':
HTTP/1.1 401 Unauthorized
HTTP/1.1 401 Unauthorized
参考文献
RFC
RFC 2617 - HTTP Authentication: Basic and Digest Access Authentication
Wikipedia
Digest access authentication - Wikipedia, the free encyclopedia
PHP の Digest 認証のサンプル
PHP: PHP による HTTP 認証 - Manual
Response の返し方
Class Phalcon\Http\Response — Phalcon 1.3.1 documentation
http://docs.phalconphp.com/ja/latest/api/Phalcon_Http_Response.html
Plugin 使い方
Phalcon で Plugin クラスを使う - Qiita
Controller での実装例(この記事書いてからこのリポジトリに気づいた)
dreamsxin/phalcon-digest-http-auth