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 の両方が設定されている場合、リダイレクト ループが発生するリスクがあります。

SecurityPlus コンポーネント:

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 に答える