Nginx и Keycloak: Идеальное сочетание для обеспечения безопасности приложений

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

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

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

1. Аутентификация

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

Как это работает: Наиболее распространенной формой аутентификации является комбинация имени пользователя и пароля. Когда пользователь вводит эти учетные данные, система сравнивает их с сохраненными данными, чтобы подтвердить его личность. Другие методы включают биометрию (например, распознавание отпечатков пальцев или лица), OTP (одноразовые пароли) и аппаратные токены.

Примеры:

Ввод пароля для входа в учетную запись электронной почты.

Использование отпечатка пальца для разблокировки смартфона.

Получение SMS-кода для подтверждения личности на сайте банка.

2. Авторизация

Определение: После того как аутентификация установлена, авторизация определяет, что разрешено делать пользователю, системе или приложению. Она отвечает на вопрос: «Есть ли у вас разрешение на выполнение этого действия?».

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

Примеры:

Обычный сотрудник может получить доступ к порталу компании, но не может вносить изменения в определенные важные документы. Администратор, напротив, может изменять, удалять и даже делиться этими документами.

В приложении для обмена файлами можно предоставить одним пользователям возможность просматривать файл, а другим - редактировать его.

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

Аутентификация гарантирует, что вы общаетесь с нужным субъектом, подтверждая его личность.

Авторизация гарантирует, что у субъекта есть разрешения на выполнение определенных действий.

Что такое шлюз (Gateway)?

Также известный как API-шлюз (API Gateway) - это инструмент, который выступает в качестве посредника для запросов от клиентов, ищущих ресурсы на других серверах или сервисах. Многие организации используют шлюзы API в микросервисных архитектурах для управления и обеспечения безопасности сложных взаимодействий между микросервисами. Популярные API-шлюзы: Amazon API Gateway, Kong, Apigee и WSO2.

Представим, что мы разрабатываем веб-приложение, состоящее из трех компонентов:

  • Одностраничное приложение (SPA), созданное с помощью таких фреймворков, как React или Angular.
  • Data Service обрабатывает все CRUD-операции, связанные с нашими доменами, и управляет подключением к базе данных.
  • Report Service получает данные из Data Service и инкапсулирует логику для генерации пользовательских отчетов.

Пример архитектуры приложения

Когда речь заходит о защите бэкенда, следует рассмотреть три основные стратегии:

1. Каждый микросервис выполняет собственную аутентификацию и авторизацию.

2. Шлюз занимается аутентификацией, а отдельные сервисы отвечают за авторизацию.

3. Шлюз обеспечивает как аутентификацию, так и авторизацию.

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

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

Keycloak - это инструмент управления идентификацией и доступом (IAM) с открытым исходным кодом, разработанный компанией Red Hat. Он предоставляет расширенные функции, такие как SSO (технология единого входа в систему), Identity Brokering (посредничество в установлении личности) и Social Login (вход в систему через социальные сети), не требуя глубоких знаний в области безопасности.

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

Nginx был создан Игорем Сысоевым в 2002 году, а первый публичный релиз состоялся в 2004 году. Изначально разработанный для решения проблемы C10K (обработка 10 000 одновременных соединений), Nginx создавался с нуля для высокоэффективности и масштабируемости.

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

Недостатки Nginx Plus

Nginx предлагает бесплатную версию своего программного обеспечения, но есть и платная версия премиум-класса, известная как Nginx Plus. В то время как Nginx Plus поддерживает единый вход с Keycloak, бесплатная версия, к сожалению, этого не делает. Это немного разочаровывает, учитывая популярность как Nginx, так и Keycloak. В TargPatrol мы используем оба инструмента, поэтому нам пришлось разработать метод, позволяющий им эффективно взаимодействовать друг с другом.

Давайте внесем некоторые изменения в нашу архитектуру. Обновленная версия изображена на рисунке ниже.

Модернизированная архитектура приложения

Как показано на рисунке, служба Nginx теперь работает как API-шлюз. Его основная роль заключается в обеспечении аутентификации и авторизации. Тем временем служба Keycloak действует как наш сервер единого входа (SSO). DataService и ReportService обрабатывают запросы, поступающие от Nginx, но они больше не управляют аутентификацией и авторизацией для этих запросов.

Я не буду углубляться в интеграцию SPA с Keycloak в этой статье, поскольку существует множество исчерпывающих ресурсов по этой теме. Например, вы можете обратиться к этому руководству__.

Как мы должны работать с аутентификацией в этом сценарии? Мы можем использовать nginx прокси аутентификации.

Пример nginx конфигурации:

http {

 ...

 location /auth {
    proxy_ssl_server_name on;
    proxy_pass  https://targpatrol-keycloak.local/realms/targpatrol-dev/protocol/openid-connect/userinfo;
    proxy_pass_request_body off;
    proxy_set_header Content-Length "";
    proxy_set_header X-Original-URI $request_uri;
 }

 location /data {
    auth_request /auth;
    auth_request_set $auth_status $upstream_status;
    error_page 401 = @handle_unauthorized;

    proxy_pass http://data-service.local;
    include /etc/nginx/common/ssl-headers.conf;

    js_content authService.authorize;
 }

 location /report {
    auth_request /auth;
    auth_request_set $auth_status $upstream_status;
    error_page 401 = @handle_unauthorized;

    proxy_pass http://report-service.local;
    include /etc/nginx/common/ssl-headers.conf;

    js_content authService.authorize;
 }
}

Что здесь происходит? Сначала мы определили /auth route, который проверяет наш запрос с помощью Keycloak. Мы просто отправляем запрос с Authorization header в Keycloak, запрашивая информацию о пользователе. Если в заголовке будет указан действительный токен, Keycloak ответит 200 OK, вернув текущие данные пользователя.

Маршруты для сервисов Data и Report содержат инструкцию 'auth_request'. Каждый раз, когда мы пытаемся получить к ним доступ, сначала будет отправлен запрос в Keycloak.

Хорошо, с процессом аутентификации мы разобрались, а как насчет авторизации? Для этого мы можем использовать функциональность nginx под названием ngx_http_js_module. Этот модуль позволяет выполнять JavaScript-код при запросе. Давайте разберемся, что такое 'js_content':

function extractPayload (token) {
  const tokenParts = token.split('.');
  const encodedPayload = tokenParts[1];
  const decodedPayload = Buffer.from(encodedPayload, 'base64').toString('utf-8');

  return JSON.parse(decodedPayload);
}

function authorize(request) {
  const token = request.headersIn.Authorization;

  if (!token || !(token.slice(0, 7) === 'Bearer ')) {
   return false;
  }

  const payload = extractPayload(token);
  const roles = payload['roles'];

  # request url
  const url = request.uri;

  # here we can compare url and roles
  # to allow or deny access

  return false;
}

Этот файл называется authService.js. Он должен содержать функцию с именем authorize, поскольку в инструкции js_content мы ссылаемся на нее как на authService.authorize (в соответствии с форматом fileName.functionName). Здесь можно использовать обычный JavaScript. Сначала мы разбираем заголовок Authorization, чтобы извлечь токен Bearer, который был сгенерирован Keycloak, в объектную форму. Затем мы можем сопоставить роли с URL-адресом запроса, чтобы либо удовлетворить, либо отклонить запрос. Все довольно просто!

Одна из проблем этого подхода заключается в том, что каждый запрос направляется в Keycloak. Возможное решение - перейти от js_content в nginx к сервису Node.js (или другому подходящему языку). Этот сервис будет иметь интеграцию с Keycloak на стороне сервера. Отметим, что эту функцию поддерживает только Nginx Plus, а не бесплатная версия. Для получения более подробной информации вы можете обратиться к: Документация Keycloak. (Keycloak’s documentation__)

Подводя итог, можно сказать, что сочетание Nginx и Keycloak представляет собой убедительное решение для обеспечения безопасности шлюза. В то время как Nginx эффективно управляет и маршрутизирует веб-трафик, Keycloak обеспечивает надежную аутентификацию и авторизацию. Их совместные возможности создают укрепленный уровень защиты, повышая удобство работы пользователей и безопасность системы. Благодаря бесшовной интеграции этих инструментов компании могут не только повысить уровень защиты, но и оптимизировать работу. Поскольку цифровой ландшафт продолжает развиваться, такие инструменты, как Nginx и Keycloak, становятся незаменимыми для тех, кто ищет сбалансированное сочетание производительности, гибкости и безопасности.