Любая динамично развивающаяся компания однажды задумывается о необходимости защиты своей информации. Казалось бы, что может быть проще: достаточно запереть в сейф все наиболее важные документы и спрятать подальше ключ... Но на деле решение проблем информационной безопасности далеко не так тривиально: как быть с электронной почтой, программами, да и без распределенных приложений компании уже не обойтись? Протокол упрощенного доступа к объектам SOAP (Simple Object Access Protocol) построен на основе протокола HTTP и идеально подходит для разработки многокомпонентных распределенных приложений, работающих в Internet.

Спецификация самого протокола SOAP и вопросы его использования в Web-приложениях достаточно подробно освещены в литературе. Для работ с SOAP можно воспользоваться и библиотекой Microsoft SOAP Toolkit, рассчитанной на среду Visual Studio 6.0. С ее помощью можно осуществить переход от COM-приложений к SOAP-приложениям.

Архитектура SOAP Toolkit

Компоненты SOAP Toolkit берут на себя основную часть служебных функций по формированию и распаковке SOAP-вызовов в формате XML, а также по транспортировке их по протоколу HTTP. Все, что остается сделать программисту, — настроить компоненты своего приложения для их последующего использования.

Оценивая данную схему с точки зрения защиты информации, можно сразу выявить слабое звено: это передача пакетов по протоколу HTTP через глобальную сеть. Действительно, вероятность перехвата вызовов локальных COM-компонентов крайне мала, но в глобальной сети любой, обладая определенным опытом, может перехватывать IP-пакеты. Для решения данной проблемы можно предложить несколько способов. Самый простой и надежный — шифрование SOAP-сообщений; конкретный механизм шифрования зависит от архитектуры приложения. Еще один способ — аутентификация пользователей и разграничение прав доступа.

Оба способа можно реализовать с помощью стандартных средств SOAP Toolkit. Вместе с тем, следует учесть, что решение будет различным в зависимости от используемого в приложении интерфейса доступа к объектам библиотеки (SOAP Toolkit позволяет использовать два интерфейса — высокого и низкого уровня).

Рис. 1. Функциональная схема приложений на основе SOAP Toolkit

Высокоуровневый интерфейс

Все операции по обработке SOAP-сообщений со стороны клиентского приложения выполняются в этом случае компонентом SOAPClient, а со стороны сервера — SOAPServer при помощи специального обработчика — «слухача». В терминологии SOAP так называют ASP- или ISAPI-приложение, выполняющее обработку HTTP-запросов и преобразование их в SOAP-вызовы.

Рассмотрим задачу построения простейшего SOAP-клиента с использованием высокоуровневого интерфейса. При наличии WSDL-файла с описанием службы (этот файл может быть сгенерирован автоматически при помощи WSDL Generator, входящего в состав библиотеки SOAP Toolkit), вызов метода удаленной службы может выглядеть так:

Листинг 1. Код высокоуровневого SOAP-клиента
'создание клиента
Dim soapClient
Set soapClient = CreateObject
  ("MSSOAP.SoapClient")
'инициализация клиента
soapClient.mssoapinit 
   "http://localhost/Sample1.wsdl",
 "Sample1", "Sample1Port"
'вызов метода
soapClient.SomeMethod

На стороне сервера этот вызов будет обработан слухачом и передан объекту SOAPServer, который произведет необходимые операции и вернет результат в виде SOAP-сообщения. Например, код ASP-страницы может выглядеть так:

Листинг 2. Код высокоуровневого ASP-слухача
'создание cервера
Dim soapServer
Set soapServer = Server.CreateObject
   ("MSSOAP.SoapServer")
'инициализация
soapServer.Init "Sample1.wsdl", 
   "Sample1.wsml"
'обработка запроса
soapServer.SoapInvoke Request,
    Response, ""

Интерфейс высокого уровня избавляет разработчика от необходимости вникать в суть процессов формирования и обработки SOAP-сообщений. Но вместе с тем он лишен и возможности какого-либо контроля над ними. В результате, зашифровать или иным образом засекретить эти сообщения не представляется возможным. Однако ситуация не столь безнадежна, как кажется: в SOAP предусмотрена возможность обеспечения защиты соединения по протоколу Secure Sockets Layer. Для того чтобы использовать возможность установки защищенного SSL-соединения, понадобится программный сертификат. При этом важно помнить, что понадобится как минимум два сертификата: один для сервера и один для клиента. В случае работы с несколькими клиентами лучше получить отдельный сертификат для каждого из них.

Далее, необходимо немного доработать код SOAP-клиента, указав на использование SSL и название сертификата, который будет использоваться для установки соединения:

Листинг 3. Код высокоуровневого SOAP-клиента с использованием SSL
'создание клиента
Dim soapClient
Set soapClient =
 CreateObject("MSSOAP.SoapClient")
SoapClient.mssoapinit
 "https://localhost/Sample1.wsdl",
 "Sample1", "Sample1Port"
'установка защищенного соединения
soapClient.ConnectorProperty("UseSSL")
 = true
soapClient.ConnectorProperty
("SSLClientCertificateName")
 = "Имя_сертификата"
'вызов метода
soapClient.SomeMethod

Код серверного приложения менять не надо, достаточно лишь установить защищенный режим («Require client certificates») на каталог Internet Information Services, который содержит файлы с описанием службы. При этом можно также включить сопоставление предъявляемых сертификатов именам пользователей домена («Enable client certificate mapping»), что позволит разрешить использование данной службы только определенным категориям пользователей, исключая неправомерный доступ к конфиденциальной информации.

SOAP Toolkit поддерживает и ряд других известных механизмов:

  • аутентификации с помощью имени и пароля;
  • аутентификации на основе Active Directory;
  • Kerberos (Windows 2000);
  • NTLM (на основе доменных имен Windows NT);
  • на основе заголовков SOAP-сообщений;
  • аутентификации через прокси-сервер.

Процедура реализации любого из этих методов аналогична случаю SSL. Достаточно лишь указать требуемые параметры соединения для SOAP-клиента (например, имя пользователя и пароль), а также настроить соответствующие права доступа к службе с помощью Internet Information Services.

Иначе обстоят дела в случае, когда нужно разграничить права доступа пользователей к отдельным методам. Поскольку стандартными средствами данную возможность реализовать нельзя, придется самостоятельно доработать код SOAP-слухача. Например, анализируя предъявляемый пользователем сертификат и запрашиваемый им метод, можно решать вопрос о разрешении или запрещении доступа. В случае ASP-слухача данные о сертификате пользователя можно получить из серверного объекта Request. К примеру, можно идентифицировать пользователя на основе имени сертификата:

Листинг 4. Код ASP-слухача с использованием SSL
'получение имени сертификата клиента
Dim sSubject
sSubject =
 Request.ClientCertificate("Subject")
'чтение SOAP-запроса
Dim soapReader
Set soapReader =
 Server.CreateObject
("MSSOAP.SoapReader")
'получаем название
 вызываемого метода
Dim sMethodName
sMethodName =
 Reader.RPCStruct.baseName
'анализ прав доступа
 на основе имени сертификата
...
Рис. 2. Настройка SSL на сервере

Низкоуровневый интерфейс

Интерфейс SOAP Toolkit низкого уровня обеспечивает гораздо большую гибкость. Его использование позволяет разработчику самостоятельно формировать SOAP-сообщения на стороне клиента и обрабатывать их на сервере. При этом используются уже другие компоненты библиотеки (такие как SOAPReader, SOAPSerializer и др.), которые обеспечивают лишь поддержку правильного формата формируемых сообщений и передачу их по протоколу HTTP. Остальное придется реализовывать самостоятельно.

Низкоуровневый интерфейс удобно использовать в том случае, когда по каким-либо причинам не устраивает защищенное SSL-соединение, например, если требуется использовать собственный алгоритм шифрования сообщений, или выполнять их подписывание с последующим журналированием вызовов. Кроме того, при формировании сообщений может возникнуть необходимость включить в тело или заголовок сообщения некоторую служебную информацию (например, данные о вызывающем компьютере). Формирование SOAP-сообщения для клиентского приложения выглядит так:

Листинг 5. Код низкоуровневого SOAP-клиента
'соединение с сервером
Dim Connector As New SoapConnector
Connector.Property("EndPointURL")
 = "http://localhost/Sample1"
Connector.Connect
Connector.Property("SoapAction")
 = "uri:" & "имя_метода"
Connector.BeginMessage
'создание объекта
 для формирования сообщения
Dim Serializer
 As New SoapSerializer
Serializer.Init
 Connector.InputStream
'формирование сообщения
Serializer.startEnvelope
Serializer.startBody
'формирование вызова метода
Serializer.startElement
 "имя_метода", "Sample1", ,"m"
Serializer.startElement
 "параметр"
Serializer.writeString
 "значение"
Serializer.endElement
Serializer.endElement
'служебная информация
Serializer.startElement
 "служебная_информация"
Serializer.writeString
 "имя_компьютера"
Serializer.endElement
Serializer.endBody
Serializer.endEnvelope
'передаем сообщение
Connector.EndMessage

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

Антон Варфоломеев (antonv@digdes.com) — сотрудник компании Digital Design (Санкт-Петербург).