Настройка аутентификации OIDC#

В этом руководстве описано, как настроить аутентификацию OpenID Connect (OIDC), используя Google в качестве провайдера идентификации и веб-сервер Angie со скриптами на Lua.

Эта реализация защищает внутренние конечные точки с помощью аутентификации OAuth2/OIDC и демонстрирует один из способов ограничить доступ по доменам электронной почты. Это лишь один из возможных подходов; вы можете реализовать контроль доступа любым удобным вам способом — например, поддерживать списки разрешённых пользователей, проверять принадлежность к домену или группам в ответе провайдера или использовать произвольные claims вашего внутреннего IAM.

Совет

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

Архитектура#

Предлагаемая конфигурация OIDC включает:

  • Angie — с поддержкой Lua-модуля для обработки OIDC

  • lua-resty-openidc — Lua-библиотека OpenResty для аутентификации через OIDC

  • Google OAuth2 — провайдер идентификации

  • Docker Compose — используется в примере только для быстрого запуска; в продакшене используйте подходящий вариант развертывания

Требования#

Перед настройкой OIDC убедитесь, что у вас есть:

  1. Веб-сервер Angie с поддержкой Lua-модуля

  2. Docker и Docker Compose (для развертывания)

  3. Проект в Google Cloud Console

  4. OAuth2-учётные данные от Google

Настройка Google OAuth2#

Чтобы настроить Google как OIDC-провайдера:

  1. Перейдите в Google Cloud Console

  2. Создайте новый проект или выберите существующий

  3. Настройте экран согласия OAuth (External или Internal) и опубликуйте его

  4. Создайте OAuth2-учётные данные:

    • Тип приложения: Web application

    • Разрешённые URI для редиректа: http://localhost/auth/callback

  5. Сохраните свои client_id и client_secret

Примечание

Стандартные Google Identity Services уже поддерживают OIDC; устаревший Google+ API не требуется. Включайте дополнительные Google API только при необходимости.

Настройка конфигурации#

Начнём с необходимых конфигурационных файлов.

Конфигурация Docker Compose#

Развёртывание через Docker использует следующий конфиг:

docker-compose.yml#
services:
  angie:
    image: docker.angie.software/angie:templated
    environment:
      ANGIE_LOAD_MODULES: "lua"
    ports:
      - 80:80
    volumes:
      - ./files/etc/angie/http.d:/etc/angie/http.d

Эта конфигурация:

  • Использует templated-образ Angie с поддержкой Lua

  • Загружает Lua-модуль для OIDC

  • Пробрасывает порт 80

  • Монтирует локальные конфигурационные файлы

Для запуска «из коробки» скачайте OIDC quick-start bundle, установите client_id и client_secret в files/etc/angie/http.d/oidc.lua, и всё сразу заработает.

Скрипт аутентификации OIDC#

Создайте скрипт OIDC, который обрабатывает логику аутентификации с использованием библиотеки lua-resty-openidc:

/etc/angie/http.d/oidc.lua#
access_by_lua_block {
    local res, err = require("resty.openidc").authenticate({
        redirect_uri = "http://localhost/auth/callback",
        discovery = "https://accounts.google.com/.well-known/openid-configuration",
        logout_path = "/auth/logout",
        redirect_after_logout_uri = "/auth/logged-out",
        revoke_tokens_on_logout = true,
        client_id = "YOUR_CLIENT_ID",
        client_secret = "YOUR_CLIENT_SECRET"
    })
}

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

  • redirect_uri: URL-адрес обратного вызова после успешной аутентификации

  • discovery: discovery-endpoint Google OIDC

  • logout_path: путь выхода пользователя

  • redirect_after_logout_uri: куда перенаправлять после выхода

  • revoke_tokens_on_logout: отзывать токены при logout

  • client_id и client_secret: учётные данные OAuth2

Конфигурация Angie#

Настройте Angie с необходимыми блоками location для аутентификации OIDC.

Защищённые ресурсы#

Чтобы защитить ресурсы:

location /internal/ {
    include /etc/angie/http.d/oidc.lua;
    proxy_pass http://127.0.0.1/status/;
}

Здесь:

Конечные точки аутентификации#

Настройка OAuth2-эндпоинтов:

location /auth/callback {
    include /etc/angie/http.d/oidc.lua;
}

location /auth/logout {
    include /etc/angie/http.d/oidc.lua;
}

location /auth/logged-out {
    default_type text/plain;
    return 200 "You have been logged out. Bye!";
}

Назначение маршрутов:

  • /auth/callback: обработка callback от Google

  • /auth/logout: инициирует выход

  • /auth/logged-out: страница после выхода

Доступ к внутреннему API#

Настройте ограниченный доступ к API:

location /status/ {
    api     /status/;
    allow   127.0.0.1;
    deny    all;
}

Это обеспечивает:

  • Доступ к status API Angie

  • Доступ только с localhost

  • OIDC-защиту при доступе через /internal/

Этапы развертывания#

Обновление конфигурации#

  1. Обновите учетные данные OAuth2 в файле Lua:

    Замените значения в oidc.lua:

    • client_id на ваш Google OAuth2 Client ID

    • client_secret на ваш Client Secret

Запуск сервисов#

  1. Запустите Docker-сервисы:

    $ docker-compose up -d
    
  2. Проверьте работу:

    • Откройте http://localhost/internal/

    • Должна появиться переадресация на Google

    • После логина вы попадёте в защищённый раздел

Настройки безопасности#

Ограничение по домену e-mail#

Реализуйте проверку домена:

if not string.match(res.user.email, "gmail.com$") then
    ngx.exit(ngx.HTTP_FORBIDDEN)
end

В продакшене:

  • замените gmail.com на домен вашей компании

  • используйте whitelist пользователей

  • добавьте контроль ролей

Управление токенами#

В реализации OIDC предусмотрено:

  • автоматический отзыв токенов при logout (revoke_tokens_on_logout = true)

  • безопасное управление сессией в lua-resty-openidc

  • следование лучшим практикам OAuth2/OIDC

Предупреждение

Для продакшена:

  • Всегда используйте HTTPS для callback-адресов

  • Храните client secrets безопасно, не в репозитории

  • Настройте корректные таймауты и обновление сессий

  • Мониторьте логи аутентификации

Поток аутентификации#

Стандартный поток OIDC выглядит так:

  1. Пользователь запрашивает защищённый URL (например http://localhost/internal/)

  2. При отсутствии сессии — перенаправление на Google OAuth2

  3. Пользователь входит в аккаунт Google

  4. Google возвращает код авторизации на /auth/callback

  5. Сервер запрашивает access token и ID token

  6. Проверяет данные пользователя (включая домен e-mail)

  7. Предоставляет доступ к ресурсу

Процесс logout:

  1. Пользователь переходит по http://localhost/auth/logout

  2. Токены отзываются у Google

  3. Локальная сессия очищается

  4. Переход на /auth/logged-out

Расширенная конфигурация#

Ограничить доступ одним доменом:

if not string.match(res.user.email, "yourcompany.com$") then
    ngx.exit(ngx.HTTP_FORBIDDEN)
end

Несколько разрешённых доменов:

local allowed_domains = {"company1.com", "company2.com", "gmail.com"}
local email_valid = false

for _, domain in ipairs(allowed_domains) do
    if string.match(res.user.email, domain .. "$") then
        email_valid = true
        break
    end
end

if not email_valid then
    ngx.exit(ngx.HTTP_FORBIDDEN)
end

Доступ к данным пользователя#

Получить дополнительные claims:

-- Доступ к данным из ID token
local user_name = res.user.name
local user_picture = res.user.picture
local user_locale = res.user.locale
local user_email = res.user.email

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