Как реализовать Basic-авторизацию для HTTP-сервиса, разработанного в 1С?

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

При разработке HTTP-сервисов в 1С часто возникает необходимость защитить доступ к ним с помощью авторизации. Один из наиболее распространенных и простых способов — использование Basic-авторизации. Этот механизм позволяет клиенту передавать учетные данные (логин и пароль) в каждом запросе в закодированном виде. Мы рассмотрим два основных подхода к реализации Basic-авторизации для вашего HTTP-сервиса 1С: на уровне самой платформы 1С через файл публикации и на уровне веб-сервера (Apache или Nginx).

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

Реализация Basic-авторизации на уровне 1С (через файл default.vrd)

Этот метод предполагает, что основной веб-сервер (Apache, IIS или Nginx, если он используется как прокси) передает запросы к 1С, а уже сама платформа 1С отвечает за проверку учетных данных, содержащихся в заголовке Authorization.

Суть подхода:

  1. Мы отключаем стандартную авторизацию 1С для публикации HTTP-сервиса, жестко прописывая имя пользователя и пароль в файле публикации (default.vrd). Это означает, что все запросы, приходящие на ваш HTTP-сервис через эту публикацию, будут выполняться от имени этого пользователя 1С.
  2. В коде самого HTTP-сервиса мы читаем заголовок Authorization из входящего HTTP-запроса, декодируем его и проверяем переданные клиентом логин и пароль.
  3. Если учетные данные верны, мы обрабатываем запрос. В противном случае, можем вернуть ошибку авторизации.

Подготовка пользователя в 1С

Прежде всего, нам необходимо создать в информационной базе 1С пользователя, от имени которого будут выполняться HTTP-сервисы. Мы рекомендуем создать отдельного пользователя с минимально необходимыми правами доступа, чтобы ограничить потенциальный ущерб в случае компрометации его учетных данных. Допустим, мы назовем его "СервисПользователь" и установим ему надежный пароль.

Настройка файла default.vrd

Файл default.vrd — это XML-файл, который генерируется при публикации информационной базы 1С на веб-сервере. Он содержит настройки публикации, включая строку подключения к базе и информацию о опубликованных HTTP-сервисах и веб-сервисах. Давайте найдем и отредактируем этот файл.

  1. Найдем файл публикации. Когда мы публиковали базу 1С, мы указывали путь для публикации. Например, для Apache это может быть каталог, указанный в директиве ManagedApplicationDescriptor в конфигурации Apache. Пройдем по этому пути и найдем файл с расширением .vrd (обычно default.vrd). Откроем его любым текстовым редактором.
  2. Отредактируем строку подключения. Внутри файла default.vrd найдем элемент <point>, который содержит атрибут ib со строкой подключения к информационной базе. Нам нужно будет дополнить эту строку учетными данными пользователя 1С, которого мы создали ранее.

    Изначально строка может выглядеть так:

    
    <point alias="MyHTTPServ" enable="true" ...>
        <ib connectionString="Srvr=&quot;SERVER&quot;;Ref=&quot;BASE&quot;;" />
        ...
    </point>
    

    Мы должны модифицировать атрибут connectionString так, чтобы он содержал логин и пароль пользователя 1С. Обратите внимание, что внутри XML-атрибута кавычки должны быть экранированы как &quot;:

    
    <point alias="MyHTTPServ" enable="true" ...>
        <ib connectionString="Srvr=&quot;SERVER&quot;;Ref=&quot;BASE&quot;;Usr=&quot;СервисПользователь&quot;;Pwd=&quot;НадежныйПароль&quot;;" />
        ...
    </point>
    

    Теперь все запросы к этому HTTP-сервису будут выполняться от имени пользователя СервисПользователь без дополнительного запроса авторизации со стороны 1С.

  3. Дополнительные настройки публикации. В настройках публикации в конфигураторе 1С рекомендуется снять галочку "Публиковать доступ для клиентских приложений", если ваш HTTP-сервис — единственный способ взаимодействия с этой публикацией. Это предотвратит попытки подключения к базе по веб-ссылке через браузер или платформу 1С в обычном пользовательском режиме. Также, после проверки HTTP-сервиса, если доступ нужен только для него, можно рассмотреть вариант установки enable="false" в элементе point, чтобы основной веб-доступ к публикации был закрыт, оставив работающими только явно указанные сервисы (хотя это зависит от версии платформы и конфигурации).
  4. Перезапустим веб-сервер. После любых изменений в файле default.vrd обязательно необходимо перезапустить веб-сервер (Apache, IIS) для применения изменений.

Обработка заголовка Authorization в HTTP-сервисе 1С

Теперь, когда запросы доходят до нашего HTTP-сервиса 1С, нам нужно извлечь и проверить учетные данные, переданные клиентом. Клиент при Basic-авторизации отправляет заголовок вида Authorization: Basic <base64_кодированные_логин_пароль>.

  1. Получим заголовки запроса. В обработчике метода нашего HTTP-сервиса мы можем получить доступ ко всем заголовкам запроса через свойство Запрос.Заголовки.
  2. Извлечем и декодируем учетные данные. Нам нужно найти заголовок Authorization, отрезать префикс "Basic " и затем декодировать оставшуюся Base64-строку.
  3. Разберем логин и пароль. Декодированная строка будет иметь вид логин:пароль. Мы разделим ее по двоеточию, чтобы получить отдельные логин и пароль.
  4. Проверим учетные данные. Мы сравниваем полученные логин и пароль с ожидаемыми (например, жестко заданными в коде, или хранящимися в каком-либо регистре сведений).
  5. Вернем ответ. Если авторизация успешна, продолжаем обработку запроса. Если нет, возвращаем HTTP-статус 401 Unauthorized с заголовком WWW-Authenticate: Basic realm="Restricted Area".

Давайте посмотрим на пример кода в модуле HTTP-сервиса:


// Пример обработчика HTTP-сервиса 1С
Функция МойМетодHTTPСервиса(Запрос)
    // Создадим объект для формирования ответа
    Ответ = Новый HTTPСервисОтвет;
    Ответ.КодСостояния = 200; // По умолчанию успешный ответ

    // 1. Получаем заголовки запроса
    ЗаголовкиЗапроса = Запрос.Заголовки;

    // 2. Ищем заголовок Authorization
    Если ЗаголовкиЗапроса.Свойство("Authorization") Тогда
        ЗначениеЗаголовка = ЗаголовкиЗапроса.Authorization;

        // Проверяем, что это Basic-авторизация
        Если СтрНачинаетсяС(ЗначениеЗаголовка, "Basic ") Тогда
            // Извлекаем Base64-кодированную строку
            КодированныеДанные = Сред(ЗначениеЗаголовка, СтрДлина("Basic ") + 1);

            Попытка
                // 3. Декодируем Base64-строку
                ДекодированнаяСтрока = БазовыеКодировки.ДекодироватьBase64Строку(КодированныеДанные, КодировкаТекста.UTF8);

                // 4. Разбираем логин и пароль (формат "логин:пароль")
                МассивДанных = СтрРазделить(ДекодированнаяСтрока, ":");

                Если МассивДанных.Количество() = 2 Тогда
                    ПолученныйЛогин = МассивДанных[0];
                    ПолученныйПароль = МассивДанных[1];

                    // 5. Проверяем учетные данные (пример с жестко заданными, можно из регистра)
                    ОжидаемыйЛогин = "MyServiceUser";
                    ОжидаемыйПароль = "MySecretPassword";

                    Если ПолученныйЛогин = ОжидаемыйЛогин И ПолученныйПароль = ОжидаемыйПароль Тогда
                        // Авторизация успешна, продолжаем обработку запроса
                        Ответ.УстановитьТелоИзСтроки("Привет, " + ПолученныйЛогин + "! Авторизация успешна.", КодировкаТекста.UTF8, "text/plain");
                    Иначе
                        // Неверные учетные данные
                        Ответ.КодСостояния = 401;
                        Ответ.Заголовки.Вставить("WWW-Authenticate", "Basic realm=""Restricted Area""");
                        Ответ.УстановитьТелоИзСтроки("Неверный логин или пароль.", КодировкаТекста.UTF8, "text/plain");
                    КонецЕсли;
                Иначе
                    // Некорректный формат данных
                    Ответ.КодСостояния = 401;
                    Ответ.Заголовки.Вставить("WWW-Authenticate", "Basic realm=""Restricted Area""");
                    Ответ.УстановитьТелоИзСтроки("Некорректный формат Basic-авторизации.", КодировкаТекста.UTF8, "text/plain");
                КонецЕсли;

            Исключение
                // Ошибка декодирования Base64
                Ответ.КодСостояния = 401;
                Ответ.Заголовки.Вставить("WWW-Authenticate", "Basic realm=""Restricted Area""");
                Ответ.УстановитьТелоИзСтроки("Ошибка декодирования авторизационных данных.", КодировкаТекста.UTF8, "text/plain");
            КонецПопытки;
        Иначе
            // Не Basic-авторизация или некорректный формат
            Ответ.КодСостояния = 401;
            Ответ.Заголовки.Вставить("WWW-Authenticate", "Basic realm=""Restricted Area""");
            Ответ.УстановитьТелоИзСтроки("Требуется Basic-авторизация.", КодировкаТекста.UTF8, "text/plain");
        КонецЕсли;
    Иначе
        // Заголовок Authorization отсутствует
        Ответ.КодСостояния = 401;
        Ответ.Заголовки.Вставить("WWW-Authenticate", "Basic realm=""Restricted Area""");
        Ответ.УстановитьТелоИзСтроки("Заголовок Authorization отсутствует.", КодировкаТекста.UTF8, "text/plain");
    КонецЕсли;

    Возврат Ответ;
КонецФункции

Преимущества данного подхода:

  1. Относительная простота реализации, так как вся логика находится внутри 1С.
  2. Не требует глубоких знаний веб-сервера.

Недостатки и важные замечания:

  1. Нагрузка на 1С: При каждой попытке авторизации (даже неудачной или при DDoS-атаке) запрос достигает 1С, что может создавать дополнительную нагрузку и замедлять работу, особенно при большом количестве запросов. Каждая попытка может приводить к созданию нового сеанса в 1С.
  2. Безопасность файла default.vrd: Пароль пользователя 1С хранится в файле default.vrd в открытом виде. Убедитесь, что доступ к этому файлу строго ограничен.
  3. Общий пользователь: Если вы прописываете пользователя 1С в default.vrd, то этот пользователь будет использоваться для всех запросов к данной публикации, включая потенциальные другие веб-сервисы или тонкий/веб-клиент, если они не отключены. Это может создать уязвимости или нежелательное поведение, если права этого пользователя слишком широки.
  4. Отсутствие кэширования: Веб-сервер не может кэшировать результаты авторизации, поскольку она происходит внутри 1С.

Реализация Basic-авторизации на уровне веб-сервера (Apache или Nginx)

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

В этом случае, в файле default.vrd не нужно указывать Usr и Pwd в строке подключения ib. 1С будет использовать логин и пароль, которые переданы веб-сервером в заголовках (обычно, если веб-сервер настроен для проксирования с авторизацией) или стандартно запрашивать их. Однако, при использовании веб-серверной авторизации, 1С не будет напрямую обрабатывать Authorization заголовок, так как он будет уже проверен. Мы можем даже полностью убрать учетные данные из default.vrd или оставить стандартную форму авторизации 1С для других целей, если это необходимо.

Реализация Basic-авторизации с использованием Apache

Apache HTTP Server имеет встроенный модуль mod_auth_basic, который позволяет легко настроить Basic-авторизацию для любого каталога или URL.

  1. Убедимся, что необходимые модули включены. Для работы Basic-авторизации нам потребуются модули:
    • mod_auth_basic: для самой Basic-авторизации.
    • mod_authn_file: для аутентификации пользователей из текстового файла.
    • mod_authz_user: для авторизации на основе имени пользователя.

    Эти модули обычно включены по умолчанию, но мы можем проверить это, например, командой apachectl -M или посмотрев конфигурационные файлы Apache (например, в каталоге mods-enabled).

  2. Создадим файл паролей (.htpasswd). Для хранения пользователей и их паролей Apache использует специальный файл, обычно называемый .htpasswd. Пароли в нем хранятся в хешированном виде.

    Для создания такого файла и добавления первого пользователя используем утилиту htpasswd, которая обычно входит в пакет apache2-utils (для Debian/Ubuntu) или httpd-tools (для CentOS/RHEL):

    sudo htpasswd -c /etc/apache2/.htpasswd myuser

    Нас попросят ввести и подтвердить пароль для пользователя myuser.

    Для добавления последующих пользователей (без перезаписи файла) мы убираем ключ -c:

    sudo htpasswd /etc/apache2/.htpasswd anotheruser

    Мы размещаем этот файл в месте, недоступном для публичного веб-доступа (например, вне корневого каталога сайта или в каталоге конфигурации Apache).

  3. Настроим конфигурацию Apache. Теперь нам нужно указать Apache использовать этот файл паролей для нашего HTTP-сервиса. Мы можем сделать это в файле конфигурации виртуального хоста или в файле .htaccess в каталоге публикации 1С (если разрешено использование .htaccess).

    Рассмотрим пример конфигурации в блоке <Directory> для каталога, где опубликована 1С:

    
    <Directory /var/www/html/1c_publication_dir>
        AuthType Basic
        AuthName "Restricted Access to 1C HTTP Service"
        AuthBasicProvider file
        AuthUserFile /etc/apache2/.htpasswd
        Require valid-user
    </Directory>
    

    Разберем директивы:

    • AuthType Basic: Указываем использовать Basic-авторизацию.
    • AuthName "Restricted Access to 1C HTTP Service": Это сообщение, которое отображается в диалоговом окне авторизации браузера.
    • AuthBasicProvider file: Указываем, что аутентификация будет происходить по файлу.
    • AuthUserFile /etc/apache2/.htpasswd: Полный путь к нашему файлу паролей.
    • Require valid-user: Требуем, чтобы любой действительный пользователь из .htpasswd мог пройти авторизацию. Мы также можем указать конкретных пользователей, например: Require user myuser anotheruser.

    Если нам нужно защитить только конкретный URL нашего HTTP-сервиса, мы можем использовать блок <Location> или <LocationMatch>:

    
    <Location /1c_publication_dir/hs/MyHTTPService>
        AuthType Basic
        AuthName "Restricted Access to My HTTP Service"
        AuthBasicProvider file
        AuthUserFile /etc/apache2/.htpasswd
        Require valid-user
    </Location>
    
  4. Перезапустим Apache. После внесения изменений в конфигурационные файлы Apache, всегда необходимо перезапустить его службу, чтобы изменения вступили в силу:
  5. sudo systemctl restart apache2

Реализация Basic-авторизации с использованием Nginx

Nginx, выступая в роли обратного прокси перед 1С, также предоставляет встроенные средства для Basic-авторизации через модуль ngx_http_auth_basic_module.

  1. Создадим файл паролей (.htpasswd). Так же, как и для Apache, Nginx использует файлы .htpasswd. Утилита htpasswd та же самая.

    Создадим файл паролей в безопасном месте, например:

    sudo htpasswd -c /etc/nginx/.htpasswd nginxuser
  2. Настроим конфигурацию Nginx. Мы добавим директивы Basic-авторизации в блок server или location нашего файла конфигурации Nginx (например, /etc/nginx/sites-available/default или файл для конкретного виртуального хоста).

    Пример настройки Nginx для проксирования на 1С с Basic-авторизацией:

    
    server {
        listen 80;
        server_name my1cservice.example.com;
    
        # Basic-авторизация
        auth_basic "Restricted Access to 1C Service";
        auth_basic_user_file /etc/nginx/.htpasswd;
    
        location / {
            proxy_pass http://localhost:8080/1c_publication_dir/; # Адрес публикации 1С на Apache/IIS
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header X-Forwarded-Proto $scheme;
    
            # Разрешаем большие размеры тела запроса, если нужно для 1С
            client_max_body_size 50m; 
        }
    
        # Если требуется защитить только конкретный HTTP-сервис
        location /hs/MyHTTPService {
            auth_basic "Restricted Access to My HTTP Service";
            auth_basic_user_file /etc/nginx/.htpasswd;
            
            proxy_pass http://localhost:8080/1c_publication_dir/hs/MyHTTPService;
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header X-Forwarded-Proto $scheme;
        }
    }
    

    Разберем директивы:

    • auth_basic "Restricted Access to 1C Service";: Включает Basic-авторизацию и определяет "realm" (сообщение для пользователя).
    • auth_basic_user_file /etc/nginx/.htpasswd;: Указывает путь к файлу с паролями.
    • proxy_pass http://localhost:8080/1c_publication_dir/;: Перенаправляет (проксирует) запросы на ваш сервер, где опубликована 1С (например, Apache на порту 8080). Обязательно указываем полный путь к публикации 1С.
    • proxy_set_header ...;: Эти заголовки крайне важны для корректной работы 1С, поскольку они передают информацию о реальном клиенте и оригинальном хосте, что может использоваться 1С для логирования или определения прав доступа.
  3. Перезапустим Nginx. После любых изменений в конфигурации Nginx, необходимо перезагрузить его службу:
  4. sudo systemctl reload nginx

Преимущества данного подхода (Apache/Nginx):

  1. Повышенная безопасность: Веб-сервер перехватывает попытки авторизации до того, как они достигнут 1С. Это защищает 1С от атак перебора паролей и снижает риск создания множества нежелательных сеансов.
  2. Высокая производительность: Веб-серверы оптимизированы для быстрой обработки авторизации и могут обрабатывать большое количество запросов с минимальными затратами ресурсов.
  3. Гибкость: Позволяет использовать дополнительные возможности веб-сервера, такие как ограничение по IP-адресам, кэширование, балансировка нагрузки и другие средства защиты.
  4. Разделение ответственности: Аутентификация вынесена на внешний уровень, что упрощает масштабирование и управление безопасностью.

Недостатки:

  1. Требует знаний по настройке веб-сервера (Apache или Nginx).
  2. Введение дополнительного компонента в архитектуру.

Важные рекомендации по безопасности

Независимо от выбранного способа реализации Basic-авторизации, мы должны соблюдать ключевые принципы безопасности:

  1. Используем HTTPS: Basic-авторизация передает логин и пароль в заголовке запроса в Base64-кодированном (но не зашифрованном!) виде. Это означает, что данные легко перехватить, если соединение не зашифровано. Критически важно использовать HTTPS для всех HTTP-сервисов, которые требуют авторизации, особенно если они доступны из интернета. Мы должны настроить SSL/TLS сертификат на нашем веб-сервере (Apache или Nginx).
  2. Разделяем ответственность: Мы уже выяснили, что аутентификация на уровне веб-сервера (Apache/Nginx) предпочтительнее. Это не только производительнее, но и безопаснее, так как платформа 1С не будет напрямую подвергаться атакам на авторизацию.
  3. Ограничиваем доступ по IP-адресам: Если наш HTTP-сервис предназначен для использования только с определенных IP-адресов (например, от партнеров или внутренних систем), мы можем настроить ограничение доступа на уровне веб-сервера.

    Для Apache:

    
    <Directory /var/www/html/1c_publication_dir>
        Require ip 192.168.1.0/24
        Require ip 10.0.0.5
    </Directory>
    

    Для Nginx:

    
    location / {
        allow 192.168.1.0/24;
        allow 10.0.0.5;
        deny all;
        # ... остальные настройки
    }
    
  4. Используем Fail2ban: Для дополнительной защиты от атак перебора паролей и других вредоносных действий мы можем настроить fail2ban. Этот инструмент анализирует логи веб-сервера и автоматически блокирует IP-адреса, с которых фиксируются многочисленные неудачные попытки авторизации.
  5. Ограничиваем права пользователя 1С: Если мы используем авторизацию через файл default.vrd, то 1С-пользователь, чьи данные там прописаны, должен иметь строго минимальные права, достаточные только для выполнения задач HTTP-сервиса. Мы не должны давать ему права администратора или полные права на все объекты.
  6. Мониторинг логов: Регулярно просматриваем логи веб-сервера (access.log, error.log) и логи 1С. Это поможет нам своевременно выявлять попытки несанкционированного доступа, ошибки и потенциальные проблемы с производительностью.
  7. Обновление сертификатов: Если мы используем HTTPS, мы должны помнить об актуальности SSL/TLS сертификатов и своевременно их обновлять. Часто для этого используют автоматизированные инструменты, такие как Let's Encrypt.

Выбирая подходящий метод и следуя рекомендациям по безопасности, мы можем эффективно защитить наш HTTP-сервис 1С с помощью Basic-авторизации.

← На главную