0

私は長い間 API に http ダイジェスト認証を使用してきましたが、期待どおりに機能したようです。

ただし、エラーが発生し、再認証を 3 回求めるプロンプトが表示されます。4 つ目は、パスワードが間違っていても、送信された電子メールのユーザーを (ユーザー名として) ログに記録するだけです。

有効なパスワードが送信されるまで再認証を続けない理由について、少し混乱しています。

    <?php


    class Model_Authentication_Init {


    const REALM = 'theaudienceauth';

    protected $user_id = NULL;
    protected $user_permissions = array();
    protected $user;
    protected $db;

    public static $instance;
    const ADMIN_PERMISSION_ID = 1;


    public function __construct() {
        $this->db = Zend_Registry::get('db');
    }


    public static function getInstance() {

        if (!isset(self::$instance)) {
            self::$instance = new self();
        }
        return self::$instance;
    }


    protected function extractData() {

        $realm = self::REALM;

        if (empty ( $_SERVER ['PHP_AUTH_DIGEST'] )) {
            header ( 'HTTP/1.1 401 Unauthorized' );
            header ( 'WWW-Authenticate: Digest realm="' . $realm . '",qop="auth",nonce="' . uniqid () . '",opaque="' . md5 ( $realm ) . '"' );
            exit ();
            die ( 'Text to send if user hits Cancel button' );
        }

        //be careful username on account isnt the same as username in the db also, later
        $data = http_digest_parse ( $_SERVER ['PHP_AUTH_DIGEST'] );
        return $data;
    }


    protected function validateData($data, $password) {

        $realm          = self::REALM;
        $A1             = md5 ( $data ['username'] . ':' . $realm . ':' . $password );
        $A2             = md5 ( $_SERVER ['REQUEST_METHOD'] . ':' . $data ['uri'] );
        $valid_response = md5 ( $A1 . ':' . $data ['nonce'] . ':' . $data ['nc'] . ':' . $data ['cnonce'] . ':' . $data ['qop'] . ':' . $A2 );

        if ($data ['response'] != $valid_response) {
            die ( 'Wrong Credentials!' );
        }
    }


    public function authData($data) {

        if (isset ($data ['username'])) {
            $account_q          = $this->db->query (" SELECT `id`, `encrypted_password` FROM `User` WHERE `email` = '".$data['username']."' AND `enabled` = 1 AND deleted = 0 ");
            $account            = $account_q->fetch ( PDO::FETCH_OBJ );
            $account_q->closeCursor();

            if (is_object ( $account )) {
                $password_fetched = decrypt_password ( $account->encrypted_password ); //@todo might need to decr.

                if (! defined ( 'CONNECTED_ACCOUNT_ID' )) {
                    define ( 'CONNECTED_ACCOUNT_ID', $account->id );
                }

                $_SESSION ['logged_in']             = 1;
                $_SESSION ['CONNECTED_ACCOUNT_ID']  = $account->id;
                $_SESSION ['email']                 = $data['username'];
                $user_permissions                   = Model_User_Permission::listing ( $account->id );
                $_SESSION['user_permissions']       = $user_permissions;
                $user_id                            = $account->id;
                $account                            = NULL;
            } else {
                die ( 'Could not auth with details passed: email: ' . $data ['username'] );
            }
        }

        $this->user_id              = $user_id;
        $this->user_permissions     = $user_permissions;
        return array($user_id, $user_permissions, $password_fetched);
    }


    /**
     * Main auth method
     * @throws Model_Exception_Application
     */
    public function auth() {

        $userId             = NULL;
        $user_permissions   = NULL;

        if (! isset ( $_SESSION ['logged_in'] ) || $_SESSION ['logged_in'] != 1) {

            $data = $this->extractData();
            list($userId, $user_permissions, $password_fetched) = $this->authData($data);

            // analyze the PHP_AUTH_DIGEST variable
            if (! ($data)) {
                throw new Model_Exception_Application ( 903 );
                die ( 'Wrong Credentials!' );
            }

            $this->validateData($data, $password_fetched);

        } else {
            if (! defined ( 'CONNECTED_ACCOUNT_ID' )) {
                define ( 'CONNECTED_ACCOUNT_ID', $_SESSION ['CONNECTED_ACCOUNT_ID'] );
            }
            $userId = $_SESSION ['CONNECTED_ACCOUNT_ID'];
            //if user permissions are not set to a session, set it
            $user_permissions = $_SESSION['user_permissions'] = Model_User_Permission::listing($userId);// isset($_SESSION['user_permissions']) && !empty($_SESSION['user_permissions']) ? $_SESSION['user_permissions'] : Model_User_Permission::listing($userId);
        }

        $this->user_id                  = $userId;
        $this->user = $_SESSION['user'] = Model_Baseclass::load_by_fields(array('table_name' => 'User', 'id' => $userId)); //isset($_SESSION['user']) && !empty($_SESSION['user']) ? $_SESSION['user'] : Model_Baseclass::load_by_fields(array('table_name' => 'User', 'id' => $userId));
        $this->user_permissions         = $user_permissions;
    }
}

上記は次のように呼び出されます。

Model_Authentication_Init::getInstance($this->rest);

編集:ずっと前のことなので、原因が今はわかりませんが、ここに行きます:

<?php


class System_Authentication_Init {


    const REALM = 'auth';

    protected $user_permissions = array();
    protected $user;
    protected $db;

    public static $instance;
    const ADMIN_PERMISSION_ID = 1;


    public function __construct() {
        $this->db = Zend_Registry::get('db');
    }


    public static function getInstance() {

        if (!isset(self::$instance)) {
            self::$instance = new self();
        }
        return self::$instance;
    }


    protected function extractData() {

        $realm = self::REALM;

        if (empty ( $_SERVER ['PHP_AUTH_DIGEST'] )) {
            header ( 'HTTP/1.1 401 Unauthorized' );
            header ( 'WWW-Authenticate: Digest realm="' . $realm . '",qop="auth",nonce="' . uniqid () . '",opaque="' . md5 ( $realm ) . '"' );
            exit ();
            die ( 'Text to send if user hits Cancel button' );
        }

        //be careful username on account isnt the same as username in the db also, later
        $data = http_digest_parse ( $_SERVER ['PHP_AUTH_DIGEST'] );
        return $data;
    }


    protected function validateData($data, $password) {

        $realm          = self::REALM;
        $A1             = md5 ( $data ['username'] . ':' . $realm . ':' . $password );
        $A2             = md5 ( $_SERVER ['REQUEST_METHOD'] . ':' . $data ['uri'] );
        $valid_response = md5 ( $A1 . ':' . $data ['nonce'] . ':' . $data ['nc'] . ':' . $data ['cnonce'] . ':' . $data ['qop'] . ':' . $A2 );

        if ($data ['response'] != $valid_response) {
            session_destroy();
            session_unset();
            session_regenerate_id();
            die ( 'Wrong Credentials!' );
        }
    }


    public function authData($data) {

        if (isset ($data ['username'])) {
            $accountQuery       = $this->db->query (" SELECT `id`, `encrypted_password` FROM `User` WHERE `email` = '".$data['username']."' AND `enabled` = 1 AND deleted = 0 ");
            $account            = $accountQuery->fetch ( PDO::FETCH_OBJ );
            $accountQuery->closeCursor();

            if (is_object ( $account )) {
                $passwordReturned = decrypt_password ( $account->encrypted_password );

                if (! defined ( 'CONNECTED_ACCOUNT_ID' )) {
                    define ('CONNECTED_ACCOUNT_ID', $account->id);
                }

                $_SESSION ['logged_in']             = 1;
                $_SESSION ['CONNECTED_ACCOUNT_ID']  = $account->id;
                $_SESSION ['email']                 = $data['username'];
                $user_permissions                   = Model_User_Permission::listing ( $account->id );
                $_SESSION['user_permissions']       = $user_permissions;
                $account                            = NULL;
            } else {
                die ( 'Could not auth with details passed: email: ' . $data ['username'] );
            }
        }

        $this->user_permissions = $user_permissions;
        return array($user_permissions, $passwordReturned);
    }


    /**
     * Main auth method
     * @throws System_Exception_Application
     */
    public function authenticate() {

        $user_permissions   = NULL;

        if (! isset ( $_SESSION ['logged_in'] ) || $_SESSION ['logged_in'] != 1) {

            $data = $this->extractData();
            list($user_permissions, $passwordReturned) = $this->authData($data);

            // analyze the PHP_AUTH_DIGEST variable
            if (! ($data)) {
                throw new System_Exception_Application ( 903 );
                die ( 'Wrong Credentials!' );
            }

            $this->validateData($data, $passwordReturned);

        } else {
            if (! defined ( 'CONNECTED_ACCOUNT_ID' )) {
                define ( 'CONNECTED_ACCOUNT_ID', $_SESSION ['CONNECTED_ACCOUNT_ID'] );
            }
            //if user permissions are not set to a session, set it
            $user_permissions = $_SESSION['user_permissions'] = Model_User_Permission::listing(CONNECTED_ACCOUNT_ID);// isset($_SESSION['user_permissions']) && !empty($_SESSION['user_permissions']) ? $_SESSION['user_permissions'] : Model_User_Permission::listing($userId);
        }

        $this->user = $_SESSION['user'] = Model_Baseclass::load_by_fields(array('table_name' => 'User', 'id' => CONNECTED_ACCOUNT_ID)); //isset($_SESSION['user']) && !empty($_SESSION['user']) ? $_SESSION['user'] : Model_Baseclass::load_by_fields(array('table_name' => 'User', 'id' => $userId));
        $this->user_permissions         = $user_permissions;
    }


    public function isAdmin() {

        if (!$this->user_permissions || empty($this->user_permissions) ) {
            $this->authenticate();
        }   

        if ($this->user_permissions) {
            foreach ($this->user_permissions as $user_permission) {
                if (isset($user_permission->{'permission_id'}) && $user_permission->{'permission_id'} == self::ADMIN_PERMISSION_ID) {
                    return true;
                }
            }
        }
        return false;
    }


    /**
     * returns user id
     * @return User id
     */
    public function getUserId() {
        return $this->user->id;
    }


    /* Added by aaron
     * returns the internal user object
     * */
    public function getUserObject() {
        Zend_Registry::set('user', $this->user);
        return $this->user;
    }


    /**
     * returns user permissions
     * @return _user_permissions User Permissions
     */
    public function getUserPermissions() {
        return $this->user_permissions;
    }


}
4

0 に答える 0