Codeigniter запрещает доступ к каталогу контроллеров с конфигурацией apache

Я хотел бы ограничить доступ к папке контроллеров, которые используются только для целей администрирования. Я пробовал несколько способов и не нашел решения. Эти контроллеры защищены паролем. Но я хотел бы просто удалить его из поля зрения, если кто-то случайно наткнется на нужный каталог. Можно ли это сделать? Я бы не хотел делать это из htaccess. У меня есть доступ к конфигурационным файлам apache, поэтому я хотел бы обработать его там.

Это как-то связано с маршрутизацией Codeigniter? Или я просто далеко?

Это то, что я использую, что не работает

<Directory /var/www/application/controllers/folder/>
  Order deny,allow
  Deny from all
  Allow from xxx.xxx.xxx.xxx
</Directory> 

person MAZUMA    schedule 05.12.2012    source источник
comment
Почему этот каталог или все приложение не установлено за пределами www, где никто никогда не сможет на него наткнуться? Одна из замечательных особенностей CI заключается в том, что она позволяет вам делать это легко.   -  person Sparky    schedule 06.12.2012
comment
Просмотрите эту тему и прокрутите вниз до заголовка Размещение каталога приложений и систем. У меня только index.php внутри www а все остальное снаружи.   -  person Sparky    schedule 06.12.2012
comment
Ok. Достаточно просто и хорошо знать. Я не верю, что это решит мою проблему с контроллерами администратора. Они находятся внутри папки контроллеров. Таким образом, если кто-то введет example.com/admin, он будет отображаться с логином. Я бы хотел, чтобы это не отображалось, если пользователь не находится за одним из двух разрешенных IP-адресов. Разве есть лучший способ?   -  person MAZUMA    schedule 06.12.2012
comment
О, понятно... Я не совсем уверен, возможно ли это, поскольку CI строит этот путь, когда вы вводите URL-адрес. Я почти уверен, что вам нужно сделать это из конфигурации маршрутов.   -  person Sparky    schedule 06.12.2012
comment
Mazuma - вы не можете сделать это таким образом - весь трафик CI идет на index.php в вашем корне - пользователь НИКОГДА не просматривает ваш контроллер напрямую - это просто выглядит так, как будто он делать. Как было предложено выше - вам нужно использовать вышеприведенную ветку для размещения всего за пределами папки www. Тогда просто ограничьте доступ к разделу администратора паролем или чем-то еще. Вы также можете выполнить проверку IP-адреса внутри CI.   -  person Laurence    schedule 06.12.2012


Ответы (2)


Из-за того, что мы переписываем URL-адреса для работы с CI, вы никогда не совпадете с конфигурацией Apache, потому что на самом деле запрашиваете index.php?{args}. Если вы хотите фильтровать, вы должны сделать это в CI. Ваши варианты: основной контроллер или хуки.

Простой способ сделать это — создать основной контроллер, который расширяется вашими сценариями администратора/зоны, и проверить там IP-адрес.

Что-то вроде этого:

application/core/MY_Controller.php:

class MY_Controller extends CI_Controller
{
    public function __construct()
    {
        parent::__construct();
        $this->load->config('permitted_ips');
        // check visitor IP against $config['ips'] array, redirect as needed
    }
}

Затем в ваших «чувствительных» контроллерах расширьте MY_Controller:

application/controllers/admin/seekrit.php

class Seekrit extends MY_Controller
{
    public function __construct() {
        parent::__construct();
        /* at this point any invalid IP has been redirected */
    }
}

Теперь, если вы уже используете основной контроллер для чего-то другого, просто проверьте $this->uri->segment(), чтобы увидеть, находятся ли они в зоне с ограниченным доступом, прежде чем загружать разрешенный файл конфигурации IP и проверять/перенаправлять/умирать или что-то еще. еще нужно сделать.

Кроме того, нет необходимости использовать конструктор в ваших контроллерах администратора, если он вам не нужен, поскольку родитель будет создан, если он не определен. Просто не забудьте позвонить родителю, если вы его определяете.

Вы также можете поместить белый список в базу данных, Redis, что угодно.

Другой способ сделать это — использовать хуки, в частности pre_controller . К моменту ввода этой ловушки все классы безопасности и базовые классы уже запущены. Это было бы уместно, если бы вы хотели более детально защитить некоторые или все свои маршруты. Там вы можете определить массив, содержащий маршруты, например:

$protected_routes = array(
    'foo' => array(
         'allow_ip' => '1.2.3.4',
         'redirect_if_not' => site_url('goaway')
     )
)

Затем в вашем классе ловушек (или функции) сопоставьте первый сегмент (в моем примере это просто функция):

$CI = get_instance();
$CI->load-config('my_hook');
$protected_routes = $CI->config->item('protected_routes');
$segment = $CI->uri->segment(1); // foo
if (in_array($segment, $protected_routes)) {

   // grab $protected_routes[$segment] and work with it
}

Преимущество этого заключается в том, что он не загромождает ваш основной контроллер, поскольку многие люди используют его как средство совместного использования кода между методами. Однако хук будет запускаться при каждом запросе, что означает добавление еще двух загрузок файлов в загрузчик.

Я использовал метод перехвата в большой службе RESTful для защиты определенных конечных точек, требуя дополнительных заголовков и применяя различные виды ограничения скорости для других. Обратите внимание: приведенный выше код является лишь примером того, что может быть внутри хука, а не того, как настроить сам хук. Прочтите раздел хуков в руководстве по CI, это очень просто и понятно.

Наконец, если вы действительно хотите сделать это через .htaccess, вам придется использовать сам запрос. Каталог application/controllers/foo никогда не используется, фактический запрос — /foo/controller/method{args}, что приводит к тому, что CI создает экземпляр класса foo/controller.php. Помните, что после перезаписи сервер видит index.php?....

Для этого вы можете переписать на основе шаблона URI запроса что-то вроде этого (не проверял, YMMV):

RewriteRule (^|/)foo(/|$) - [F,L]

Который можно использовать для перенаправления любого, кто обращается к виртуальному пути, к вашим защищенным контроллерам. Это может быть предпочтительнее, поскольку избавляет PHP от необходимости обрабатывать его, но вы теряете детальный контроль над тем, что происходит при совпадении. Тем не менее, вы можете использовать что-то вроде приведенной выше перезаписи в сочетании с хуком или основной реализацией, если вам нужно защитить более одной чувствительной области.

person Tim Post♦    schedule 23.12.2012

Идея Тима Поста выше похожа на другой метод, который я видел либо на этом сайте, либо где-то еще. Мне потребовалось некоторое время, чтобы вернуться к этому вопросу, но, наконец, это сделано.

Как указал TheShiftExchange в комментариях к моему первоначальному вопросу, .htaccess не будет работать для проекта Codeigniter. Ниже приведено то, что я в конечном итоге получил и, кажется, работает хорошо. Вероятно, это не на 100% безопасно, но я действительно просто хотел удалить эти страницы из прямого доступа. Если кому-то удастся попасть на страницу, все равно будет экран входа пользователя/пароля.

Новый файл конфигурации в application/config

switch (ENVIRONMENT) //set in index.php
{
    case 'development':
        $config['admin_ips'] = array('XXX.XXX.XXX.XXX');
        break;
    case 'testing':
        $config['admin_ips'] = array('XXX.XXX.XXX.XXX', 'XXX.XXX.XXX.XXX', 'XXX.XXX.XXX.XXX');
        break;
    case 'production':
        $config['admin_ips'] = array('XXX.XXX.XXX.XXX', 'XXX.XXX.XXX.XXX', 'XXX.XXX.XXX.XXX');
        break;
}

Новый контроллер

class Admin_IP_Controller extends MY_Controller {
    function __construct()
    {
        parent::__construct();
        $this->load->config('admin_ips');
        if (!in_array($this->input->ip_address(), $this->config->item('admin_ips')))
        {
            show_404();
        }
    }
}
person MAZUMA    schedule 11.01.2013