2015-01-26 3 views
5

Я разрабатываю очень простую систему управления доступом RBAC (Role Based Access Control) в своем проекте PHP, и, подумав, что я придумал решение, но не зная о создании бизнес-систем, я не уверен, что есть или будут какие-либо серьезные недостатки дизайна с моим решением.Является ли мой контроль доступа на основе роли доступным решением?

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

Вот роли таблицы:

# Roles 
    - id [auto-increment, unsigned] 
    - role [string, length:50] 

# User_Roles 
    - user_id [FK:user_id, unsigned] 
    - role_id [FK:roles_id, unsigned] 

Note: user_id and role_id to be unique index 

Проблема, что касалось меня там не было никакой информации в базе данных о том, что на самом деле делает роль. Но потом я начал думать, если это важно. Потому что, если роли были осмысленные имена и структура, то вы можете запросить таблицу user_roles, чтобы получить все роли пользователей, а затем в коде что-то вроде:

# Fetch user with ID 1 from database 
$user = User::find(1); 

# Fetch the roles the user has from the database 
# @returns : Array of roles 
$userRoles = $user->roles() 

# $userRoles = ['newmember', 'member.post', 'member.chat'] 

# Can the user send a message? 
if(in_array('member.message', $userRoles) 
{ 
    # User can send a message 
} 
else 
{ 
    # User can not send a message 
} 

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

Мое решение будет осуществимо в долгосрочной перспективе?

Благодаря

+2

вы всегда можете добавить дополнительные поля в таблицу 'role', чтобы хранить объяснения того, для чего это нужно. Но, в конце концов, фактическое название роли не имеет значения. Это сводится к тому, что соответствующая «требует ли пользователь роли» проверяет, становится ли это разрешение. Является ли это разрешение «42» или «is_superuser», не имеет большого значения. –

+1

Я рекомендую прочитать эту статью: http://www.yiiframework.com/doc/guide/1.1/en/topics.auth#role-based-access-control и попробуйте использовать для этого некоторую фреймворкную структуру, потому что все это охлаждают системы RBAC. – stepozer

+0

@stepozer Я работаю с Laravel, у которого нет встроенной системы, но предоставляет фильтры маршрутов и промежуточное ПО, которые я буду использовать с помощью специального решения. Я хочу, чтобы не добавлять дополнительные пакеты, поскольку они слишком переполнены. Мне нужно простое решение. –

ответ

18

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

Подумайте о модулях как сущностях/ресурсах в вашем приложении, на которых могут выполняться определенные действия. Ресурс может быть ПОЛЬЗОВАТЕЛЬ, членство, продукт, ..

Давайте предположим, что мы строим сайт как Stackoverflow и мы имеем следующие модули:

  • Вопросы (Q & раздел)
  • Чат

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

# Modules 
    - id [an application-wide unique module identifier, provided by the module] 
    - name [string, human readable] 

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

# Actions 
    - module_id [reference to the modules table, is the namespace for the token] 
    - action [string/int, action identifier provided by the module, unique in the scope of the module] 
    - name [string, human readable name] 

    - Primary Key: [module_id, action] 

Давайте определим модули и действия для нашего клона StackOverflow Сейчас:

Modules 
+------------------------------------------+ 
| ID  | Name       | 
+------------------------------------------+ 
| questions | Question and Answer Module | 
| chat  | Chat Module     | 
+------------------------------------------+ 

Наряду с модулями, будут установлены действия:

Actions 
+-----------------------------------------------+ 
| Module | Action | Name     | 
+-----------------------------------------------+ 
| questions | read  | Read Questions  | 
| questions | create | Create Questions  | 
| questions | edit  | Edit Questions  | 
| questions | delete | Delete Questions  | 
| questions | vote  | Vote on Questions  | 
|   |   |      | 
| chat  | join  | Join the Chat   | 
| chat  | kick  | Kick users   | 
| chat  | create | Create Chatrooms  | 
+-----------------------------------------------+ 

Важным здесь является то, что вы не можете изменить данные в этих таблицах непосредственно в качестве администратора систем, так что нет GUI , чтобы добавить/удалить действия и т.д.

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

Давайте начнем с некоторых основных ролях:

Q&A User: 
    - can read questions 
    - can create questions 
Q&A Moderator: 
    - can read questions 
    - can create questions 
    - can vote on questiosn 
    - can edit questions 
Q&A Admin: 
    - can read questions 
    - can create questions 
    - can vote on questiosn 
    - can edit questions 
    - can delete questions 

Chat User: 
    - can join the chat 

Chat Moderator: 
    - can join the chat 
    - can kick users from the chat 

Chat Admin: 
    - can join the chat 
    - can kick users from the chat 
    - can create chat rooms 

Во-первых, роли создаются в таблице ролей:

# Roles 
    - id [auto-increment, unsigned] 
    - name [string, length:50] 

Населенные с нашими пользовательских определений:

Roles 
+-----------------------+ 
| ID | Name    | 
+-----------------------+ 
| 1 | Q&A User   | 
| 2 | Q&A Moderator | 
| 3 | Q&A Admin  | 
| 4 | Chat User  | 
| 5 | Chat Moderator | 
| 6 | Chat Admin  | 
+-----------------------+ 

В нашем супермощном пользовательском интерфейсе администратора теперь есть боковая панель со списком всех установленных модулей и их ассоциатов действия. Начиная с наш типичный администратор супер ленив и ничего не знает о программировании, он теперь может удобно назначать действия для каждой роли с помощью drag & drop, т. Е. Назначая разрешения для ролей.

Этих назначенных разрешений хранится в нашей таблице отображения Roles_Actions:

# Roles_Actions 
    - role_id 
    - module_id 
    - action 

    PK: [role_id, module_id, action] 

заселенный стол:

Roles_Actions 
+--------------------------------+ 
| Role ID | Module ID | Action | 
+--------------------------------+ 
| 1 | questions | read | 
| 1 | questions | create | 
| 2 | questions | read | 
| 2 | questions | create | 
| 2 | questions | vote | 
| 2 | questions | edit | 
       ... 
| 6 | chat | join | 
| 6 | chat | kick | 
| 6 | chat | create | 
+--------------------------------+ 

Теперь мы должны назначить роли для пользователей в системах, скажем мы имеют первоначально четырех пользователей:

- Chuck Norris which is a Q&A Admin and also a Chat Admin (UID = 1) 
- Bruce Willis which is a Q&A Moderator and a Chat User (UID = 2) 
- Dilbert which is a Q&A Moderator and a Chat Moderator (UID = 3) 

# User_Roles 
    - user_id [FK:user_id, unsigned] 
    - role_id [FK:roles_id, unsigned] 

Заселенный стол:

Users_Roles 
+---------------------------------+ 
| User ID | Role ID    | 
+---------------------------------+ 
| 1 | 3 (= Q&A Admin)  | 
| 1 | 6 (= Chat Admin)  | 
| 2 | 2 (= Q&A Moderator) |  
| 2 | 4 (= Chat User)  | 
| 3 | 2 (= Q&A Moderator) | 
| 3 | 5 (= Chat Moderator) | 
+---------------------------------+ 

Так один пользователь может иметь несколько ролей и разрешений (пар модуль/действие), затем объединены вместе в уровне приложений. Если вы хотите перейти на один шаг дальше, вы также можете предоставить какое-то наследование в ролевой модели, например Q & Модератор может быть определен как дочерний элемент Q & Пользователь, наследующий все разрешения от Q & A Пользователь и распространяя его на права модератора.

Так как же может возникнуть авторизация на уровне приложения?

Предположим, что Dilbert, который является Q & Модератор Модератор и Чат, регистрируется в системе, затем вы собираете все его роли и все права, назначенные этим ролям.Затем вы начинаете строить дерево разрешения и удалить все дубликаты разрешений, дерево разрешение может быть представлена ​​в виде ассоциативного массива, как:

Дилберта разрешение дерева:

$dilberts_permissions = array(
    "questions" => array("read", "create", "vote", "edit") 
    "chat"  => array("join", "kick") 
) 

Для удобства мы создаем простую вспомогательную функцию как:

function has_permission($path, $tree) { 
    list($module, $action) = explode('.', $path); 
    return (array_key_exists($module, $tree) && in_array($action, $tree[$module])); 
} 

в нашем коде теперь мы можем проверить, если Дилберта разрешено делать определенные вещи с синтаксисом, как:

has_permission("questions.create", $dilberts_permissions); // => TRUE 
has_permission("questions.delete", $dilberts_permissions); // => FALSE 
has_permission("chat.join", $dilberts_permissions);   // => TRUE 
has_permission("chat.create", $dilberts_permissions);  // => FALSE 
Смежные вопросы