Введение

Списки контроля доступа (ACL) — это метод управления доступом к ресурсам в системе. Это механизм безопасности, используемый для регулирования доступа к ресурсам на основе личности пользователя и назначенных ему привилегий. ACL используются в самых разных системах, включая операционные системы, базы данных, веб-приложения и сети. В этой статье мы рассмотрим ACL и то, как они работают.

Что такое АКЛ?

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

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

Как работают списки управления доступом?

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

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

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

Реализация ACL в коде

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

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

Например, в приложении React вы можете использовать библиотеку react-router-dom для определения маршрутов для вашего приложения и пользовательский компонент высшего порядка withAccessControl для переноса компонентов маршрута. Компонент withAccessControl будет проверять личность и разрешения пользователя перед рендерингом обернутого компонента.

Давайте посмотрим на мой пример, сначала набираем types.ts :

export interface Route {
  path: string;
  component: React.ComponentType<any>;
  title: string;
  exact?: boolean;
  acl: {
    [key in Role]: {
      type: DecisionType;
      meta?: string;
    };
  };
}

export enum Role {
  GUEST = 'guest',
  USER = 'user',
  ADMIN = 'admin',
}

export enum DecisionType {
  ALLOW = 'allow',
  DENY = 'deny',
  REDIRECT = 'redirect',
}

Затем routes.ts :

import { Route, Role, DecisionType } from './types';

import HomePage from './pages/HomePage';
import ProfilePage from './pages/ProfilePage';
import DashboardPage from './pages/DashboardPage';
import AdminPage from './pages/AdminPage';
import LoginPage from './pages/LoginPage';

export const routes: Route[] = [
  {
    path: '/',
    component: HomePage,
    title: 'Home Page',
    exact: true,
    acl: {
      [Role.GUEST]: {
        type: DecisionType.ALLOW,
      },
      [Role.USER]: {
        type: DecisionType.ALLOW,
      },
      [Role.ADMIN]: {
        type: DecisionType.ALLOW,
      },
    },
  },
  {
    path: '/profile',
    component: ProfilePage,
    title: 'Profile Page',
    exact: true,
    acl: {
      [Role.GUEST]: {
        type: DecisionType.REDIRECT,
        meta: '/login',
      },
      [Role.USER]: {
        type: DecisionType.ALLOW,
      },
      [Role.ADMIN]: {
        type: DecisionType.ALLOW,
      },
    },
  },
  {
    path: '/dashboard',
    component: DashboardPage,
    title: 'Dashboard Page',
    exact: true,
    acl: {
      [Role.GUEST]: {
        type: DecisionType.REDIRECT,
        meta: '/login',
      },
      [Role.USER]: {
        type: DecisionType.ALLOW,
      },
      [Role.ADMIN]: {
        type: DecisionType.ALLOW,
      },
    },
  },
  {
    path: '/admin',
    component: AdminPage,
    title: 'Admin Page',
    exact: true,
    acl: {
      [Role.GUEST]: {
        type: DecisionType.REDIRECT,
        meta: '/login',
      },
      [Role.USER]: {
        type: DecisionType.REDIRECT,
        meta: '/',
      },
      [Role.ADMIN]: {
        type: DecisionType.ALLOW,
      },
    },
  },
  {
    path: '/login',
    component: LoginPage,
    title: 'Login Page',
    exact: true,
    acl: {
      [Role.GUEST]: {
        type: DecisionType.ALLOW,
      },
      [Role.USER]: {
        type: DecisionType.REDIRECT,
        meta: '/',
      },
      [Role.ADMIN]: {
        type: DecisionType.REDIRECT,
        meta: '/',
      },
    },
  },
];

Этот код экспортирует массив из Route объектов, представляющих маршруты веб-приложения. Каждый объект Route содержит следующие свойства:

  • path: строка, представляющая путь маршрута.
  • component: компонент, который будет отображаться при доступе к маршруту.
  • title: строка, представляющая заголовок страницы, связанной с маршрутом.
  • exact: логическое значение, указывающее, должен ли маршрут точно соответствовать или нет.
  • acl: объект, представляющий список управления доступом для маршрута. Объект acl содержит три свойства, guest, user и admin, которые соответствуют трем возможным ролям, которые может иметь пользователь. Значением каждого свойства является объект, определяющий решение по управлению доступом для этой роли, включая type решения (либо ALLOW, либо REDIRECT) и meta данные, связанные с решением (либо путь для перенаправления, либо null для ALLOW решений). .

Этот код также импортирует интерфейсы Route, Role и DecisionType из модуля types.ts, который определяет эти интерфейсы для использования во всем приложении. Кроме того, он импортирует пять компонентов страницы (HomePage, ProfilePage, DashboardPage, AdminPage и LoginPage), связанных с маршрутами.

И, наконец, файл App.tsx, который является корнем приложения:

const withAccessControl = (Component: React.ComponentType, acl: RouteConfig['acl']) =>
  (currentUserRole: Role) => {
    const decision = acl[currentUserRole];
    if (!decision || decision.type === DecisionType.ALLOW) {
      return <Component />;
    } else if (decision.type === DecisionType.REDIRECT) {
      return <Redirect to={decision.meta || '/'} />;
    }
    return null;
  };

const App = () => {
  const currentUserRole = Role.USER; // replace this with the current user's role

  return (
    <Router>
      <Switch>
        {routes.map(({ path, component, exact, acl }) => (
          <Route
            key={path}
            path={path}
            exact={exact}
            render={() => withAccessControl(component, acl)(currentUserRole)}
          />
        ))}
      </Switch>
    </Router>
  );
};

export default App;

Этот код определяет функцию высшего порядка withAccessControl, которая принимает два аргумента — компонент React и конфигурацию ACL (список управления доступом).

Функция возвращает функцию, которая принимает параметр Role, представляющий текущую роль пользователя.

Возвращаемая функция проверяет конфигурацию ACL для роли текущего пользователя и возвращает соответствующее решение. Если принято решение ALLOW, возвращается исходный компонент. Если принято решение REDIRECT, компонент Redirect из пакета react-router-dom возвращается с реквизитом to, установленным на указанное мета-значение. Если решение не найдено или тип решения не распознан, возвращается null.

Компонент App использует функцию withAccessControl для переноса компонентов, указанных в массиве routes. Для каждого маршрута рендерится компонент Route из пакета react-router-dom с переданными реквизитами пути, компонента, точного и ACL. Для реквизита render устанавливается функция withAccessControl, которая вызывается с указанным компонентом и конфигурацией ACL, а роль текущего пользователя. Это гарантирует, что только пользователи с соответствующими разрешениями могут получить доступ к указанным маршрутам.

Заключение

ACL — важный механизм безопасности, используемый для управления доступом к ресурсам в системе. Они обеспечивают детальный контроль над тем, какие действия пользователи могут выполнять с определенными ресурсами, и обычно используются в операционных системах, базах данных, веб-приложениях и сетях. Реализация ACL в коде требует сочетания механизмов аутентификации и авторизации, обычно с использованием промежуточного программного обеспечения для проверки личности пользователя и разрешений перед предоставлением доступа к ресурсу.