Маленький ВЕБ-сервис с большими возможностями

Представьте, что у вас есть несколько баз данных, похожих и не похожих друг на друга, возможно, разделенных просторами интернета. Намерение, например, что-то одновременно поменять в них, записать новый элемент справочника, снять однотипные отчеты упирается в волну неприятного предвкушения полазить по терминалкам ради захода в каждую базу, если не предусмотрено средств работы с базами из одного места. ВЕБ-сервисы предоставляют подходящий для интернета транспорт для передачи данных и локализуют ресурсоемкие COM-соединения в пределах связки каждой пары сервер 1С и веб-сервер.

При этом для использования в рамках платформы 1С совершенно не обязательно углубляться в собственную структуру веб-сервиса, разрабатывать его объектную модель и интерфейсы. Достаточно выставить через сервис фунцию вида CmdExec(ParamStructure: string):string и гонять между базами строки, получаемые функцией ЗначениеВСтрокуВнутр(). Если в одном из полей структуры передавать код обработки данных на языке 1С, получаем всемогущий инструмент. Итак, прототип функции веб-сервиса всего лишь

Функция CmdExec(ParamStructure)

СтруктураПараметров = ЗначениеИзСтрокиВнутр(ParamStructure);
Результат = Новый Структура;
Если СтруктураПараметров.Свойство("КодОбработки") Тогда
Попытка
Выполнить(СтруктураПараметров.КодОбработки);
Исключение
Результат.Вставить("Ошибка",ОписаниеОшибки());
КонецПопытки;
Иначе
Результат.Вставить("Ошибка","WS.ПСГ_Общий.CmdExec: Входная структура не содержит свойства КодОбработки.");
КонецЕсли;
ВозвращаемоеЗначение = ЗначениеВСтрокуВнутр(Результат);

Возврат ВозвращаемоеЗначение;

КонецФункции

В прилагаемой демонстрационной базе создан веб-сервис ПСГ_Общий, выставляющий приведенную функцию CmdExec. Для удобства использования применяется функция ПСГ_ОбработчикиВебСервисов.ВыполнитьКомандуЧерезВебСервис(Адрес,СтруктураПараметров,КодОбработки), принимающая на входе адрес веб-сервера, произвольную структуру параметров и код обработки данных, и возвращающая структуру, созданную функцией CmdExec на целевой базе.

Функция   ВыполнитьКомандуЧерезВебСервис(Адрес,СтруктураПараметров,КодОбработки) Экспорт

СтрокаСоединения = Адрес + "/ws/wsGeneral.1cws?wsdl";

wsAccount = wsAccount();
Определения = Новый WSОпределения(СтрокаСоединения,wsAccount.Логин,wsAccount.Пароль);
Прокси = Новый WSПрокси(Определения,"http://www.promstroi-group.ru/general","ПСГ_Общий","ПСГ_ОбщийSoap");
Прокси.Пользователь = wsAccount.Логин;
Прокси.Пароль = wsAccount.Пароль;

СтруктураПараметров.Вставить("КодОбработки",КодОбработки);
ДанныеСтрокой = Прокси.CmdExec(ЗначениеВСтрокуВнутр(СтруктураПараметров));
Если ДанныеСтрокой = Неопределено Тогда
ВызватьИсключение("Не удалось получить данные");
КонецЕсли;

Данные = ЗначениеИзСтрокиВнутр(ДанныеСтрокой);
Если Данные.Свойство("Ошибка") Тогда
ВызватьИсключение(Данные.Ошибка);
КонецЕсли;

Возврат Данные;

КонецФункции

Здесь wsAccount() возвращает данные для авторизации в виде структуры(«Логин,Пароль»).

Рассмотрим простейший «Hello, world» для нашего веб-сервиса, команду Ping, выясняющую, доступен ли сервис.

Функция Ping(Адрес) Экспорт

СтруктураПараметров = Новый Структура;
КодОбработки = "Результат.Вставить(""Статус"",""онлайн"");";
Результат = ПСГ_ОбработчикиВебСервисов.ВыполнитьКомандуЧерезВебСервис(стр.АдресWS,СтруктураПараметров,КодОбработки);
Попытка
Возврат Результат.Статус;
Исключение
Возврат ОписаниеОшибки();
КонецПопытки;

КонецФункции

Демонстрационная база содержит три других примера: обработку Демо, считывающую произвольный справочник целиком, обработку Тиражирование объектов WS, позволяющую скопировать объект в выбранные базы с совпадающей по составу объектов (но не обязательно реквизитов) структурой.

Для установки демонстрационной базы нужно загрузить прилагаемую dt-выгрузку в новую пустую базу 1С и опубликовать ее на веб-сервере. Далее, в клиенте нужно зайти в справочник Базы данных, и прописать адрес базы в поле Веб-сервер у базы данных База 1, и выставить константу Эта база данных = База1. После этого демонстрационные обработки уже могут общаться с самой этой же базой через ее веб-сервис. Но, конечно, значительно интереснее создать еще одну копию базы, прописать ее в справочник Базы данных как База 2 и посмотреть общение между этими базами.

Не лишне предупредить, что знающий логин и пароль wsAccount(), обладает, фактически правами пользователя wsAccount().Логин в базе, и правами пользователя, под которым работает сервер 1С (или IUSR в файловом варианте), в операционной системе.

9 Comments

  1. WKBAPKA

    что то после пива не совсем вкурил… чуствую, что что-то полезное, но пока не могу понять, что…

    Reply ↓
  2. irreal

    Коротко говоря, отправляешь другой базе код, который нужно выполнить и его параметры структурой, и получаешь ответ структурой. Веб-сервис здесь лишь приспособленный к интернету транспорт. Практически вместо этого можно было бы применить COM-коннектор, но этот, прежде чем заработать, прокачает через инет весь cf. С веб-сервисом тоже прокачает, но не через инет, а между сервером 1с и веб-сервером, через инет пойдет полезный только объем.

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

    База — сервер:

    Функция ОбщийМодуль.БольшаяИСложнаяТаблица(СтруктураПараметров) Экспорт

    …МногаБукав

    КонецФункции

    База-клиент:

    СтруктураПараметров = Новый Структура;

    …Заполнение структуры

    КодОбработки = «Результат.Вставить(«»БольшаяТаблица»»,ОбщийМодуль.БольшаяИСложнаяТаблица(СтруктураПараметров));»;

    Результат = ПСГ_ОбработчикиВебСервисов.ВыполнитьКомандуЧерезВебСервис(стр.АдресWS,СтруктураПараметров,КодОбработки);

    // Вот большая таблица и получена:

    БольшаяТаблица = Результат.БольшаяТаблица;

    Конечно, следует учитывать, в каких терминах будет этот ответ. Если это разные конфигурации, то ссылки «оттуда» потеряют смысл, и нужно возвращать гуиды и наименования. То есть, работа не похожа на работу с объектной системой ком-коннектора. Но в случае, если имеется много одинаковых баз, да еще поддерживается сквозная НСИ, все вообще великолепно.

    Reply ↓
  3. cool.vlad4

    (2) конечно, замечательно, и идея достаточно простая и понятная, ну кто не думал, сделать Выполнить во внешней базе, и через внешнее соединение и даже через ВК (на этом сайте видел, 1CHServer как-то так называется). Вот только вопрос безопасности остался в сторонке. К сожалению в 1С нет безопасного Выполнить (или мне он неизвестен), т.е. правильно ли я понимаю, что работа таким образом через интернет это серьезная брешь в безопасности ИБ?

    Reply ↓
  4. irreal

    (3) Снижение до уровня защиты в авторизации 1С — безусловно. К тому же, нужно извратиться, чтобы скрыть получение логина и пароля в коде, если к коду имеют доступ, например, аутсорсеры.

    С другой стороны, выставить в открытый интернет базу данных я не решился бы и без этого. Интернет интернетом, но в рамках приличия — VNP. На предмет наличия злоумышленника, перехватывающего пакеты внутри сети — да, место слабое.

    К слову сказать, мне пока не удалось заставить клиент веб-сервиса 1С авторизоваться по аутентификации ОС, поэтому в коде есть это самое wsAccount() — действие, чью имплементацию я намеренно вынес в отдельную функцию. Если бы удалось ввести виндовую авторизацию, дело обстояло бы гораздо лучше.

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

    Reply ↓
  5. DitriX

    (3) в платформе 8.3 появился Безопасный режим. Т.е. вы работать можете только в среде 1С, и вам не доступно внешнее окружение.

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

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

    (0)Короче — это вариант не новый, его уже в разных видах представляли тут.

    Вот если вы попробуете пройтись по всем аналогичным темам и решить все проблемы там описанные, ответить на все вопросы, вот тогда будет гут.

    Reply ↓
  6. asved.ru

    Зачем применять строковое преобразование, если можно использовать прекрасно сериализующееся ХранилищеЗначения?

    Reply ↓
  7. irreal

    (6) asved.ru, логично, можно и так.

    Reply ↓
  8. artbear

    Очень опасная схема 🙁

    Кто угодно может выполнить код 1С в любой базе 🙁

    Reply ↓
  9. irreal

    (8) artbear, Для этого «кому угодно» нужно, как минимум, знать логин и пароль веб-сервиса. Выполнение внешних обработок ползователями у нас запрещено, так что здесь не прорвешься, даже зная API. В конце концов, Выполнить() используется, например, в УниверсальныйОбменДаннымиXML. Можно, подсунуть вредоносные правила пользователю этой обработки, если она вдруг ему доступна.

    Reply ↓

Leave a Comment

Ваш адрес email не будет опубликован. Обязательные поля помечены *