1

CakePHP 在 SecurityComponent 中有一个 requireSecure 函数。在传递信用卡号等敏感信息时,我使用它来强制使用 SSL。

问题:

  • 有 requireNonSecure 功能吗?
  • 如果没有 requireNonSecure 函数,是否可以在不修改原始文件的情况下扩展/添加函数到 CakePHP 的核心文件?

我想要一个 requireNonSecure 功能,因为我的一些页面嵌入了只能在我们的域名上播放的视频。使用 SSL 时,视频托管服务无法识别我们的域名并且无法播放视频。

这是控制器的 beforeFilter 中的一些代码:

function beforeFilter() {
    parent::beforeFilter();

    $this->Security->validatePost = false; // disable CSRF protection
    $this->Security->blackHoleCallback = 'forceSSL';
    $this->Security->requireSecure('pay', 'index');

    $this->Auth->allow('index');
}

这是 app_controller.php 中的回调

function forceSSL() {
    $redirect = '';
    if (!empty($this->params['url']['redirect'])) {
        $redirect = '?redirect=' . $this->params['url']['redirect'];
    }

    $this->redirect('https://' . rtrim(env('SERVER_NAME'), '/') . $this->here . $redirect);
}
4

2 回答 2

1

一种解决方案是将函数附加到 beforeFilter ,如下所示:

在控制器中:

function beforeFilter() {
    parent::beforeFilter();

    // Require non secure (http) for video action
    $this->requireNonSecure('video');

    // ... other code here

}

在 app_controller.php 中:

function requireNonSecure() {
    $requireNonSecure = array_map('strtolower', func_get_args());

    if (in_array(strtolower($this->action), $requireNonSecure) || $requireNonSecure == array('*')) {
        if ($this->RequestHandler->isSSL()) {
            $this->redirect('http://' . rtrim(env('SERVER_NAME'), '/') . $this->here);
            return;
        }
    }
}
于 2012-06-21T18:53:02.097 回答
0

此解决方案添加到 SecurityComponent。它应该可以工作,但如果同时设置了 requireSecure 和 requireNonSecure,则存在重定向循环的风险。

安全加组件:

class SecurityPlusComponent extends SecurityComponent {

    /**
     * List of actions that do not require an SSL-secured connection
     *
     * @var array
     * @access public
     * @see SecurityPlusComponent::requireNonSecure()
     */
    var $requireSecure = array();

    /**
     * Component startup. All security checking happens here.
     *
     * @param object $controller Instantiating controller
     * @access public
     */
        function startup(&$controller) {
            $this->_action = strtolower($controller->action);
            $this->_methodsRequired($controller);
            $this->_secureRequired($controller);
            $this->_nonSecureRequired($controller);
            $this->_authRequired($controller);
            $this->_loginRequired($controller);

            $isPost = ($this->RequestHandler->isPost() || $this->RequestHandler->isPut());
            $isRequestAction = (
                !isset($controller->params['requested']) ||
                $controller->params['requested'] != 1
            );

            if ($isPost && $isRequestAction && $this->validatePost) {
                if ($this->_validatePost($controller) === false) {
                    if (!$this->blackHole($controller, 'auth')) {
                        return null;
                    }
                }
            }
            $this->_generateToken($controller);
        }

    function requireNonSecure() {
        $this->_requireMethod('NonSecure', func_get_args());
    }

    /**
     * Check if access requires non secure connection (http)
     *
     * @param object $controller Instantiating controller
     * @return bool true if secure connection required
     * @access protected
     */
    function _nonSecureRequired(&$controller) {
        if (is_array($this->requireNonSecure) && !empty($this->requireNonSecure)) {
            $requireNonSecure = array_map('strtolower', $this->requireNonSecure);

            if (in_array($this->_action, $requireNonSecure) || $this->requireNonSecure == array('*')) {
                if ($this->RequestHandler->isSSL()) {
                    if (!$this->blackHole($controller, 'nonSecure')) {
                        return null;
                    }
                }
            }
        }
        return true;
    }
}

修改 app_controller forceSSL 函数:

function securityBlackhole($type) {
    $redirect = '';
    if (!empty($this->params['url']['redirect'])) {
        $redirect = '?redirect=' . $this->params['url']['redirect'];
    }

    // Force http (non-SSL)
    if($type == 'nonSecure') {
        $this->redirect('http://' . rtrim(env('SERVER_NAME'), '/') . $this->here . $redirect);

    // Force https (SSL)
    } else {
        $this->redirect('https://' . rtrim(env('SERVER_NAME'), '/') . $this->here . $redirect);
    }
}

在控制器中会这样调用:

function beforeFilter() {
    parent::beforeFilter();

    $this->SecurityPlus->validatePost = false; // disable CSRF protection
    $this->SecurityPlus->blackHoleCallback = 'securityBlackhole';
    $this->SecurityPlus->requireSecure('pay', 'index');
    $this->SecurityPlus->requireNonSecure('video');

    $this->Auth->allow('index');
}
于 2012-06-21T18:52:13.777 回答