четверг, 19 июля 2012 г.

Управление доступом - 2. Авторизация.

Права и обязанности пользователя

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

Довольно распространенное решение в части управления правами выглядит так:
  •  есть набор некоторых объектов, доступ к которым надо ограничить;
  • есть набор некоторых ролей доступа, каждая из которых имеет право доступа к одному или нескольким объектам;
  • каждый пользователь имеет роль доступа.
Для осуществления такой схемы нам понадобятся:
Таблица со списком пользователей. Возьмем таблицу USERS из предыдущего поста и дополним ее столбцом ROLE_ID.
Таблица со списком ролей. Назовем ее ROLES, создадим столбцы ID и ROLE_NAME.
Таблица со списком объектов доступа. У меня на данный момент объектами доступа являются действия, которые пользователь может совершать, поэтому таблица называется ACTIONS, а столбцы в ней, соответственно - ID и ACTION_NAME.
Таблица для связи ролей и доступных действий. Так как нам желательно иметь связь типа "многие-ко-многим" между таблицами ROLES и ACTIONS, создаем еще одну таблицу ACTIONS_OF_ROLES со столбцами ID, ACTION_ID и ROLE_ID.

Авторизация

На закладке Security в свойствах страницы есть два поля: Authorization Scheme и Authentication. Первое поле показывает, какая схема авторизации используется для страницы, вторая - открыт ли доступ к странице (на выбор есть два варианта - Page Is Public или Page Requires Authorization). Поле Authorization Scheme есть так же и у любого элемента страницы - у регионов, кнопок, полей для ввода, процессов и т. д. Изначально там есть два варианта:
No Page Authorization Required - доступ будет открыт для всех, или
Must Not Be A Public User - страницу будет видеть только пользователь, который прошел авторизацию (ввел правильный логин и пароль на странице регистрации). В этом случае все пользователи будут обладать равными возможностями доступа. А если, как говорится, все наши пользователи равны, но некоторые - равнее? Специально для них можно создать отдельную схему авторизации, которая дополнительно будет проверять, к какой группе пользователей относится наш пользователь.
Схемы авторизации создаются в разделе Shared Components -> Authorization Scheme. Мастер создания простой и короткий, состоит из двух шагов: на первом выбираем способ создания - "с нуля" или на основе существующей схемы, на втором - задаем имя, тип вычисляемого выражения (SQL-выражение, PL/SQL-функция, возвращающая логическое значение, какое-либо выражение), само выражение, текст сообщения об ошибке и точку вызова - при каждом просмотре страницы или один раз за сессию. Например, мы хотим сделать страницу для особо привелегированных пользователей (администратор системы, который будет раздавать права пользователям попроще). Соответственно, мы добавляем строку в таблицу ACTIONS (действие "управление доступом"), две строки - в таблицу ROLES (одна строка - роль простого пользователя и одна строка - роль админа). В таблицу  ACTIONS_OF_ROLES мы добавляем строку, связывающую роль админа с действием "управление доступом". Схему назовем ACCESS_MANAGEMENT. Теперь осталось написать PL/SQL функцию, которая будет проверять, есть ли доступ у пользователя к странице, на которой можно посмотреть и изменить права пользователя.
Возьмем, для примера, такую PL/SQL функцию:
  
declare
  rec_cnt integer;
begin
  select count(*)
    into rec_cnt
    from a_action_of_roles actsr
       , users s
   where s.role_id = actsr.role_id
     and s.login = upper(APEX_CUSTOM_AUTH.GET_USER)
     and actsr.action_id = 1;
-- 1 в последней строке условия - это захардкоденное значение поля action_id, 
-- соответствующее нужной вам строке таблицы ACTIONS

  return (rec_cnt > 0);

  exception
    when no_data_found then return false;
end;

Теперь мы можем зайти в свойства нужной нам страницы и в поле Authorization Scheme выбрать ACCESS_MANAGEMENT. Если, например, на другой странице приложения нужно создать кнопку, которая будет перенаправлять пользователя на страницу управления доступом, и показывать эту кнопку только пользователям с ролью админа, то в свойствах этой кнопки тоже можно установить эту схему авторизации.

Регистрация пользователей

Остался последний вопрос. Так или иначе, но в таблицу пользователей нужно поместить информацию о логине и пароле. Как я уже говорил, пароль лучше всего хранить в зашифрованном виде. Для сохранения пользователей в базе можно использовать примерно такую функцию:
  
create or replace procedure "CREATE_USER"
(p_login      in VARCHAR2,
 p_pwd        in VARCHAR2)
is
  apwd varchar2(128);
begin
  if p_pwd is not null then
     apwd:=dbms_obfuscation_toolkit.md5(input_string => p_pwd);
  end if;
  
  insert into users (LOGIN, PWD)
  values (upper(p_login), apwd);

end;

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

Комментариев нет:

Отправить комментарий