Magento后端模块导致404

Since the SUPEE-5994 patch in Magento I seem to be getting a 404 error while requesting a function within a controller, before this patch, this function was working fine. According to this post, it has to do something with the config.xml but as far as I know, this does not apply for the adminhtml blocks that have to be called from a Controller. I also cannot find if this error is a result from the patch that routers need to be defined.

I tried adding a router with all the controllers and the blocks but even after clearing the cache, logging out and in again, the function still is a 404.

This is my code:

app/code/community/MyModule/Advanced/Controller/AjaxController.php

class Icepay_IceAdvanced_AjaxController extends Mage_Adminhtml_Controller_Action
{

    protected $webservice = null;

    public function iceWebservice()
    {
        if ($this->webservice == null)
            $this->webservice = new Icepay_IceAdvanced_Model_Paymentmethods();
        return $this->webservice;
    }

    public function indexAction()
    {
        $this->loadLayout();
        $this->renderLayout();
    }

    public function get_paymentmethodsAction()
    {
        $this->getResponse()->setBody(Zend_Json::encode($this->iceWebservice()->retrieveAdminGrid($this->getRequest()->get("store"))));
    }

    public function save_paymentmethodAction()
    {
        $adv_sql = Mage::getSingleton('iceadvanced/mysql4_iceAdvanced');

        $reference = $this->getRequest()->getPost("reference");
        $scopeID = $this->getRequest()->getPost("store");

        if (!isset($reference))
            return;

        $adv_sql->setScope($scopeID);

        $settings = Mage::helper("iceadvanced")->getPaymentmethodExtraSettings();

        if ($this->getRequest()->getPost("active_issuers")) {
            $issuers = explode(",", $this->getRequest()->getPost("active_issuers"));
            if (count($issuers) >= 1)
                array_push($settings, "active_issuers"); //At least 1 issuer active is required
        }

        foreach ($settings as $setting) {
            $adv_sql->saveConfigValue($reference, $setting, $this->getRequest()->getPost($setting));
        }

        $this->getResponse()->setBody(sprintf($this->__("%s settings have been saved."), $this->getRequest()->getPost("name")));
    }

}

app/code/community/MyModule/Advanced/Block/Adminhtml/Grid/Paymentmethods.php

class Icepay_IceAdvanced_Block_Adminhtml_Grid_PaymentMethods extends Mage_Adminhtml_Block_Widget implements Varien_Data_Form_Element_Renderer_Interface
{

    protected $_element;
    protected $_scope;
    protected $_ajaxLoadPaymentMethodURL;
    protected $_ajaxSavePaymentMethodURL;
    protected $_ajaxGetPaymentMethodsURL;
    protected $debug;

    public function __construct()
    {
        $this->_scope = Mage::app()->getStore(Mage::helper("icecore")->getStoreFromRequest())->getId();
        $this->_ajaxLoadPaymentMethodURL = Mage::helper('adminhtml')->getUrl('icepayadvanced/config/index/paymentmethod/{{pm_code}}', array('_secure' => true, 'scope' => $this->_scope));
        $this->_ajaxSavePaymentMethodURL = Mage::helper('adminhtml')->getUrl('icepayadvanced/ajax/save_paymentmethod', array('_secure' => true, 'scope' => $this->_scope));
        $this->_ajaxGetPaymentMethodsURL = Mage::helper('adminhtml')->getUrl('icepayadvanced/ajax/get_paymentmethods', array('_secure' => true));

        $this->setTemplate('icepayadvanced/grid_paymentmethods.phtml');
    }

    public function render(Varien_Data_Form_Element_Abstract $element)
    {
        $this->setElement($element);
        return $this->toHtml();
    }

    public function setElement(Varien_Data_Form_Element_Abstract $element)
    {
        $this->_element = $element;
        return $this;
    }

    public function getElement()
    {
        return $this->_element;
    }

    public function getJS($uri)
    {
        return Mage::getBaseUrl(Mage_Core_Model_Store::URL_TYPE_JS, true) . $uri;
    }

    public function getPaymentmethods()
    {
        return Mage::getSingleton('iceadvanced/mysql4_iceAdvanced')->getAdminPaymentmethodConfigForStore($this->_scope);
    }

    public function getAddButtonHtml()
    {
        return $this->getChildHtml('add_button');
    }

    protected function _prepareLayout()
    {
        $button = $this->getLayout()->createBlock('adminhtml/widget_button')
            ->setData(array(
                'label' => Mage::helper('icecore')->__('Get paymentmethods'),
                'onclick' => 'return ICEPAY.retrieveFromICEPAY()',
                'class' => 'add'
            ));
        $button->setName('add_tier_price_item_button');

        $this->setChild('add_button', $button);

        if (version_compare(Mage::getVersion(), '1.7.0.0', '<')) {
            $this->getLayout()->getBlock('head')->addItem('js_css', 'prototype/windows/themes/magento.css');
        } else {
            $this->getLayout()->getBlock('head')->addItem('skin_css', 'lib/prototype/windows/themes/magento.css');
        }

        $this->getLayout()
            ->getBlock('head')
            ->addItem('js_css', 'prototype/windows/themes/default.css');

        return parent::_prepareLayout();
    }

}

Here I uploaded the config.xml and any other file for review.

Edit: After following BJ Hoffpauir guide; this is the output of the error.log

192.168.137.1 - - [17/Jul/2015:23:03:56 +0000] "POST /index.php/icepayadvanced/ajax/get_paymentmethods/key/21e4f55bb33ad6a323c50140bc5ef585/?isAjax=true HTTP/1.1" 404 16910 "http://192.168.137.124/index.php/admin/system_config/edit/section/icecore/key/e96d9f50648cad8168ebf376470196ad/" "Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/43.0.2357.134 Safari/537.36"

This is more likely after applying the latest patch SUPEE-6285 which made another change for adminhtml controllers.

Now you have to implement the _isAllowed() method in the controller, otherwise it is only accessible for admin users with full permissions.

See this question at Magento.SE: https://magento.stackexchange.com/q/73646/243

Ricardo, there are a few folders and files that may have had their permissions set to 777 when Magento originally created them that are updated by the patch.

I would suggest running through the following file and folder permissions doc from Magento to ensure that after you have installed the patch, you can confirm that all file and folder permissions are set to the recommended security ACL's as defined in this guide.

NOTE : By default, that guide basically has you disabling the functionality of Magento Connect which is a good idea for your production sites - you don't want ANYONE installing software directly onto you productions system without testing and archival in a source code repository like git / hg / svn ... if you DO need to use that functionality, that guide provides instructions on how to temporarily loosen permissions enough to use the utility, then how to restore the more security settings when you are done.

Follow this guide, it will most likely solve your 404 issues. If it does not, locate your Apache or Nginx web server log file and grep it for the 404 error - for example my logs are stored in

/var/log/apache2/access.log
/var/log/apache2/error.log

on my Ubuntu 14.04 system and when I run the command

cat /var/log/apache2/error.log | grep 404

I might see output like the following:

[Sun Jul 12 21:39:54.824860 2015] [:error] [pid 1234] [client 10.10.10.10:51404] script '/var/www/html/script.php' not found or unable to stat
[Sun Jul 12 21:39:54.824860 2015] [:error] [pid 1234] [client 10.10.10.10:51404] script '/var/www/html/script.php' not found or unable to stat

Paste what YOU find when you run that cat command replacing the /var/log/apache2/error.log with wherever YOUR web server log file is stored. Edit your questions & paste what you find in your question and we can help you locate the source of the 404 error and the specific context in which it is generating the error.

Based on the information in the supplied pastebin:

"192.168.137.1 - - [20/Jul/2015:08:39:03 +0000] "GET /index.php/admin/system_config/edit/section/icecore/key/e43339d0ca7181a8e347c7e991ef840f/ HTTP/1.1" 200 23324 "http://192.168.137.124/index.php/admin/system_config/index/key/d266293b931243779092e7c1d1c5f84d/" "Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/43.0.2357.134 Safari/537.36"
"192.168.137.1 - - [20/Jul/2015:08:39:09 +0000] "POST /index.php/icepayadvanced/ajax/get_paymentmethods/key/743d139de39f76ead943a8651787de64/?isAjax=true HTTP/1.1" 404 16910 "http://192.168.137.124/index.php/admin/system_config/edit/section/icecore/key/e43339d0ca7181a8e347c7e991ef840f/" "Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/43.0.2357.134 Safari/537.36"

The first call (GET) hitting the endpoint at /index.php/admin/system_config/edit/section/icecore/key/e43339d0ca7181a8e347c7e991ef840f/ is successfully returning a 200 response.

The second call (POST) hitting the endpoint at /index.php/icepayadvanced/ajax/get_paymentmethods/key/743d139de39f76ead943a8651787de64/?isAjax=true is failing with the 404

There is only four reasons I can see that happening:

  1. there is no underlying file at the location you are specifying in the xml configuration.
  2. The file's permissions do not allow it to be read by the web server process
  3. You still need to implement the _isAllowed() method as expected post-SUPEE-6285. I agree with kel's comment in this answer from Fabian in that you shouldn't JUST return true as that opens up a security vulnerability (admittedly hard to access if you can't login to the admin panel). Also, after reviewing the GitHub source for the module, I agree with Fabian's comments on this answer that since there's no Adminhtml.xml or ANY existing ACL in the current config.xml you'll have to implement it yourself OR request the vendor perform the update.

I have to agree with Fabian who is much more experienced than I in this regard: I don't understand how a route that is only defined in the Frontend could have ever worked to provide an Adminhtml interface.

It COULD be that there was some odd quirk that allowed this behavior to function that was also closed up with one of the recent patches, but even if that were the case, adding support for _isAllowed in some fashion would probably still be required.

I've added the following into config.xml and it solved the problem:

<admin>
    <routers>
        <iceadvanced>
            <use>admin</use>
            <args>
                <module>Icepay_IceAdvanced</module>
                <frontName>icepayadvanced</frontName>
            </args>
        </iceadvanced>
    </routers>
</admin>

`