Мелкозернистый контроль доступа - PullRequest
4 голосов
/ 05 октября 2009

Я знаком с целым рядом способов аутентификации пользователей для веб-приложения администрирования, которое мы разрабатываем, и даже с различными методами, позволяющими следить за авторизацией ...

Однако мой вопрос к вам: как бы вы порекомендовали мне реализовать механизм детального контроля доступа, который предлагает следующее:

  1. Пользователи принадлежат к «ролям» или «группам», таким как «продавец», «планирование» и т. Д.
  2. Система меню администратора показывает только «страницы», которые имеют функции, относящиеся к роли (ам) пользователя
  3. Специфические функции на этих страницах имеют ограничения - например, на странице «Новое бронирование» пользователи «продавца» могут оформить бронирование «только в будущем», а на странице «Редактировать бронирование» можно редактировать бронирования ». через неделю ». Однако «планирующим» пользователям может быть разрешено ретроспективно бронировать «до недели назад» и редактировать заказы, сделанные ими на «любой период времени», но заказы, сделанные другими только «до завтра» ...

Я знаю, что могу реализовать базовую систему на основе ролей для удовлетворения требований № 1 ... У меня такое чувство, что я должен разделить все приложение на куски кода, каждый из которых имеет свои собственные отношения objectID -missionsID, чтобы я мог сканировать База данных разрешений, чтобы увидеть, какие объекты доступны - это помогло бы мне с №2.

Любые идеи, как я мог бы создать, например, элемент управления формой, который для «продаж» пользователей отображает только дату в будущем (но отображает даты до «недели назад» для планирующих пользователей), а затем каким-то образом связывает это с строка в анализаторе POST, которая проверяет, действительно ли дата находится в ожидаемом диапазоне?

Я поиграл с идеей, что я должен сохранять каждый кусок кода в базе данных, а затем иметь таблицу объектов, которая динамически создает код в соответствии с таблицей разрешений, так что единственным «файлом» на сервере является db. файл подключения!

Любые идеи приветствуются ... (даже если вы не php / MySQL)


Еще немного понимания проблемы из презентации CUSEC Зеда Шоу, рассказывающей о том, почему "ACL мертв" - http://vimeo.com/2723800

Ответы [ 4 ]

4 голосов
/ 05 октября 2009

Внимание, впереди много Zend Framework!

Вы можете легко обрабатывать 1. и 2. с помощью Zend_Acl и Zend_Navigation .

Для номера 3 вам нужно будет запросить объект ACL в вашей модели и сделать много вещей вручную. Вы также можете использовать Zend Framework для форм и включить специальные валидаторы элементов формы в зависимости от разрешения роли пользователя.

EDIT:

Если вам не хочется идти по маршруту ZF, вы можете хотя бы взглянуть на то, как обрабатывается ACL в ZF.

2 голосов
/ 24 августа 2010

Если вы хотите построить настоящий детальный контроль доступа (FGAC), просто проверьте мою статью на эту тему для MySQL:

Детальный контроль доступа MySQL 5.0 (FGAC)

По сути, вы не хотите, чтобы ваш бизнес-код зависел от реализации FGAC, вы не хотите смешивать код FGAC в пункте where операторов select ваших бизнес-правил. В этой статье показаны решения, позволяющие избежать загромождения операторов SQL.

1 голос
/ 05 октября 2009

В стремлении реализовать «нативный» подход, вместо того, чтобы поддерживать фреймворк, я поиграл со следующим. Кто-нибудь оценит этот подход? Вы предвидите какие-либо подводные камни?

// Check database for existence of this $user against this $object.
function get_permission($user, $object){
    // Query goes here...
    if( ... ){
        return $permission;
    } else {
        return FALSE;
    }
}

Приведенная выше функция будет запрашивать базу данных и выводить что-то вроде этого:

// Result of role-object query.  
role_ID      object_ID          permission  
-------      ---------          ----------
salesperson  new_booking_date   'min' => 'now', 'max' => '+1 year'  
planning     new_booking_date   'min' => '-1 week', 'max' => '+1 year'  
salesperson  edit_booking_date  'this_user_min' => 'now', 'this_user_max' => '+1 week', 'other_user_min' => 'now', 'other_user_max' => '+1 week'  
planning     edit_booking_date  'this_user_min' => '-1 week', 'this_user_max' => '+1 year', 'other_user_min' => '-1 week', 'other_user_max' => '+1 week'  

Следующий код на странице, содержащей форму ввода:

// Draw form control with javascript date validation...
$this_permission = get_permission($this_user, 'new_booking_date');
if($this_permission){
    $html->datepicker('min' => $this_permission['min'], 'max' => $this_permission['max']);
}

После того, как бронирование было сделано, другая страница позволяет нам редактировать это поле:

// Verify POST data...
$this_permission = get_permission($this_user, 'edit_booking_date');
if($this_permission){
    if($this_user == $author_user && $_POST['date'] >= strtotime($this_permission['this_user_min'], $date_ref) && $_POST['date'] <= strtotime($this_permission['this_user_max'], $date_ref)){
        // Update database...
    } elseif($_POST['date'] >= strtotime($this_permission['other_user_min'], $date_ref) && $_POST['date'] <= strtotime($this_permission['other_user_max'], $date_ref)){
        // Update database...
    }
}

Я на трассе Ригт?

0 голосов
/ 28 июля 2012

Я разработал библиотеку под названием PHP-Bouncer , которая, я думаю, удовлетворит ваши потребности. В настоящее время он поддерживает полностью управляемый доступ, который позволит вам использовать один вызов на каждой странице (я, конечно, рекомендую использовать включение) и автоматически перенаправлять людей, если у них нет доступа к странице, а также автоматический поиск ролей из база данных (если вы реализуете роли в БД с помощью прилагаемого сценария установки таблицы MySQL). Синтаксис довольно прост.

Вы создаете вышибалу:

$bouncer = new Bouncer();

Добавьте свои роли (вручную):

// Add a role     Name,      Array of pages role provides
    $bouncer->addRole("Public", array("index.php", "about.php", "fail.php"));
// Add a role          Name,              Array of pages role provides
    $bouncer->addRole("Registered User", array("myaccount.php", "editaccount.php", "viewusers.php"));
// Add a role          Name,   Array of pages role provides       List of pages that are overridden by other pages
    $bouncer->addRole("Admin", array("stats.php", "manageusers.php"), array("viewusers.php" => "manageusers.php"));

или из базы данных:

// conf_* values are set in a config file, or you can pass them in explicitly
$bouncer->readRolesFromDatabase(conf_hostname, conf_username, conf_password, conf_schema, "mysql");

Добавьте пользователя и назначьте ему несколько ролей (Примечание. Существует класс с именем BouncerUser, который может расширять ваш класс User, он предоставляет все необходимые вам функции ролей!):

$user->addRole("Logged In"); // This Role doesn't exist in the bouncer, but we can set it anyways if we feel like setting another flag on the user's account. This can be useful for displaying content in a page only if a user has a secondary role.
$user->addRole("Public");
$user->addRole("Registered User");

Затем пусть Bouncer управляет доступом к вашим файлам:

$bouncer->manageAccess($user->getRoles(), substr($_SERVER["PHP_SELF"], 1), "fail.php");
// Any time the user tries to go to a page they don't have access to, they will get to
// fail.php. Any time they try to go to a page that is overridden for them, they will 
// get to the overriding page.

Если вы хотите показывать контент на странице, только если у пользователя есть разрешение на его просмотр, просто оберните его в:

if($user->hasRole("Registered User")){
    echo "The content";
}

Я думаю, что для описанной вами проблемы это было бы отличным решением!

...