ZendFrameworkでベーシック認証を試みる 自作編
( PHP )わけって、アプリ側(ZendFramework)でもベーシック認証できないかということで調べてみたらありました。
流れとしては、
1. 認証を行う対象のコントローラがリクエストされたら、認証用のリクエストを送信する 2. パスワードファイルは指定されたディレクトリから情報読み込み、そこから認証のチェックを行う 3. 認証できれば当該処理を終了させる 4. 認証できなければ、401にする
今回はプラグイン側で実行することにします。
/** * My_Controller_Plugin_HttpBasicAuth * */ class My_Controller_Plugin_HttpBasicAuth extends Zend_Controller_Plugin_Abstract { /** * Basic認証 * * @param Zend_Controller_Request_Abstract $request */ public function dispatchLoopStartup(Zend_Controller_Request_Abstract $request) { // init $server = $this->getRequest()->getServer(); $htpasswdFile = "/home/html/public_html/.htpasswd"; // 処理系のアクションか? if (file_exists($htpasswdFile) && is_file($htpasswdFile)) { // init $response = $this->getResponse(); $request = $this->getRequest(); // htpasswdから情報取得 $htpasswds = file($htpasswdFile); // headerから情報取得 $authHeader = $request->getHeader('Authorization'); // 認証情報解析 $cryptPass = ''; $cryptUser = ''; if (preg_match('/Basic (.+)/', $authHeader, $matches)) { $base64 = base64_decode($matches[1]); $userInfo = explode(':', $base64); $cryptUser = $userInfo[0]; // パスワード情報があるまでチェックする foreach ($htpasswds as $line) { if (empty($line)) { continue; } $htpasswd = My_Util::trimAll(explode(':', $line)); $username = array_get($htpasswd, 0); $password = array_get($htpasswd, 1); // 送信されたパスワード $cryptPass = crypt($userInfo[1], substr($password, 0, 2)); // 値は等しいければ終了 if ($password == $cryptPass && $username == $cryptUser ) { return; } } } // 認証リクエスト送信 $response->setRawHeader('HTTP/1.1 401 Authorization Required'); $response->setRawHeader('WWW-Authenticate: Basic realm="My User"'); // 認証画面設定 $response->clearBody(); $request->setControllerName('error') ->setActionName('authrequired') ->setDispatched(false); } } }
最後にapp.iniにプラグインを有効化して終了。
resources.frontController.plugins.HttpBasicAuth.class = "My_Controller_Plugin_HttpBasicAuth"
ベーシック認証の仕組みを理解してれば、容易くいけるものですね。
base64でデコードしてあげればいいだけですもの。
の。