Книги, научные публикации Pages:     | 1 | 2 | 3 | 4 | 5 |

том 2 альманах програ иста Тематический сборник материалов Library и Magazine ASP.NET Web-сервис Web-приложения альманах программиста Составитель Ю. Е. ...

-- [ Страница 3 ] --

Рис. 2. IIS Как IIS обрабатывает пути без расширения (вроде report)? Он проверяет, соответствует ли виртуальный путь существующе му физическому каталогу. Если да, IIS просматривает список документов по умолчанию и ищет совпадение с именем из этого списка. Если совпа дение найдено, клиент перенаправляется на соответствующий ресурс, как я уже рассказывал. В ином случае просто возвращается сообщение об ошибке HTTP 404 File not (файл не На самом деле IIS переправляет не все вызовы, а только те из них, в которых URL не за канчивается слэшем (/) или не указывает на файл. Кроме того, отсутствие в каталоге до кумента по умолчанию не вызывает ошибку 404. В этом случае чаще всего сообщается об отсутствии у вас прав на доступ к данному Ч Прим.

Microsoft Теперь, вооружившись этими знаниями, возвращается к бизнес-аналитику и объясняет ей, что вместо в проекте надо использовать расширение файлов наподобие payroll.

Если бизнес-аналитик принимает это решение, разработчик может задей ствовать интерфейс из ASP.NET. Объекты, реализующие этот способны напрямую обрабатывать HTTP-запросы. Web форма фактически компилируется в класс, производный от класса отде ленного кода (code-behind>

Самый важный метод в IHttpHandler Ч Он принимает аргумент типа HttpContext. Этот аргумент предоставляет доступ ко всем полезным объектам вроде Request, Response и т. д. Мне нужно, чтобы HTTP-обработчик разбирал (parse) виртуальный путь и перенап равлял запрос на другую страницу. Я предпочитаю реализовать перенап равление на серверной стороне, чтобы не требовать лишнего ответа от кли ента. Для перенаправления я метод эквивалент ный тому, который поддерживается в ASP.

Единственное, на что еще я хотел бы обратить ваше внимание: как класс HttpHandler сообщает форме ASP.NET название компании.

извлекает это название из виртуального пути URL. В данном случае я ис пользовал набор (collection) (Страница ASP.NET мо жет получать название компании через выражение <%=Context.Items Код, реализующий обработчик перенаправления, пока зан на рис. 3.

Рис. 3. Обработчик using using public fiedirectionHttpHandler :

{ public * путь // на и см. след. стр.

мониторинг и Рис. 3. Обработчик перенаправления * - 1);

* Дstring 1, - // Разбить =, * Server. + Т > public get } } Реализовав класс и упаковав его в сборку, вы должны настроить Web-сайт на запуск этого обработчика при каждом запросе. Настройка понадобится в двух местах. Во-первых, в файл надо добавить кото рая сопоставляет с вашим обработчиком все содержащие расшире ние Вот как это сделал я:

Microsoft P.NET Во-вторых, вы должны настроить IIS так, чтобы тот переадресовывал зап росы на файлы с расширением исполняющей среде ASP.NET.

Это делается либо программно, либо через пользовательский интерфейс IIS (рис. 4). DLL исполняющей среды ASP.NET, находит ся в каталоге вида Конкретный каталог для этой DLL зависит от версии Framework, поэтому самый безопасный способ найти нужную DLL Ч посмотреть, ка кая DLL сопоставлена с ASPX-файлами. Надеюсь, что в следующих вер сиях IIS, которые будут полнее поддерживать такой поиск не потре буется.

0 to:

Рис. 4. Сопоставление расширения Подробнее о реализации и настройке HTTP-обработчика см. по ссылке Перезапись URL с помощью Если вы дочитали до этого места, значит, вас скорее всего интересует уни версальное решение, которое позволило бы сопоставлять любой с ASP- или ASPX-файлами без рассмотренных ранее ограничений. Един ственный известный мне способ заключается в отказе от Framework и возврате к добрым старым Дело в том, что Ч это HTTP-обработчики, родные для IIS, и они выполняются на очень ранней стадии запросов (до кода ASP.NET).

С концептуальной точки зрения, очень похожи на HTTP в ASP.NET. Главное их отличие в том, что ISAPI-фильтры следует писать на С или C++. По ISAPI-фильтрам есть масса литературы, и я лишь кратко поясню, что они собой представляют (более подробную информа цию см. на и www.microsoft.com/mind/0797/isapitips.htm).

Перехват, и На практике Ч это Windows DLL, которая предоставляет две точки входа:

DWORD HttpFllterProc( DWORD BOOL WINAPI GetFilterVersion( Исполняющая среда IIS вызывает функцию Get Filter Version при инициа лизации фильтра. Через эту функцию фильтр должен сообщить IIS об интересующих его событиях. Потом, когда будут поступать HTTP-запро сы, IIS будет вызывать по одному разу для каждого собы тия, на уведомление о котором зарегистрировался данный фильтр. Чтобы слегка упростить эту задачу, вы можете использовать MFC-класс Ч удобную оболочку голого С API. Данный класс переправляет со бытия одному или нескольким реализованным вами виртуальным мето дам. Далее я исхожу из того, что вы работаете с такой MFC-оболочкой (см.

также который перезаписывает URL и сохраняет часть виртуального пути в псевдозаголовке, представлен на рис. 5. Для перезаписи URL нуж но перехватывать событие Весь фокус в использовании специального URL для чтения исходного. После того как URL перезапи сан, вы можете с помощью SetHeader установить специальный URL и тем самым заставить IIS вызвать ваш файл. Код на изменяет URL вида на Обратите вни мание на то, как удаляется название компании и добавляется суффикс.aspx.

Кошмарно выглядящая часть кода отвечает за извлечение названия компа нии и сведение воедино остальной части URL для выполнения запроса.

Рис. 5. Решение на основе * 409В;

char * DWORD pfc, // URL, используя специальный * см. след. стр.

Рис. 5. Решение на основе if "url", // Фильтр только к каталогу bestpayroll if cPrefix, urlSize * urlSize;

char pPage;

страницы в обратном char* - 1;

// * pPage;

// сразу за / while // за // Поиск обратном - pPage);

pCompany] "url", Остается последнее: как ASP.NET исходный URL или на звание компании. Очевидного способа взаимодействия между ISAPI и ASP или не существует. Я могу лишь добавить но вый заголовок Ч Этот заголовок можно считывать из ASP.NET через набор Request. Variables:

Перехват, мониторинг и Здесь я логику, отвечающую за перезапись URL, в С++-код.

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

Заключение На примере простой задачи перезаписи я продемонстрировал вам разные способы фильтрации HTTP-вызовов. ASP.NET предоставляет но вые способы такой фильтрации, использующие преимущества CLR, что в большинстве случаев очень удобно. если вам нужно фильтровать вызовы на самых ранних этапах обработки (до того как начинает работать ASP или ASP.NET), придется прибегнуть к программированию на C++.

Исходный код для этой статьи можно скачать по ссылке load.microsoft.com/download/msdnmagazine/code/Aug02/WXP/EN-US/ Панос Коугиоурис (Panos Ч архитектор нескольких Интернет приложений на основе и других технологий. С ним можно связаться по адресу panos@acm.org.

Тим и Кит Браун HTTP-конвейеры Безопасная реализация обработки фильтрации и переадресации контента в ASP.NET Ч и расширяемая среда для HTTP-программирования на серверной стороне. Хотя большинство рассматривает ASP.NET лишь как среду для обслуживания за ней стоит более низкоуровневая ра. Эта инфраструктура на конвейере или цепочке, в которую соединяются приложение, модуль и объекты-обработчики. Чтобы задействовать все возможности ASP.NET как серверной платформы, повы сить эффективность процессов и защитить нужно понимать, как работает этот конвейер. В статье объясняется архитектура конвейера и как использовать его для добавления изощренной нальности в приложение ASP.NET.

Большинство рассматривает ASP.NET лишь как среду для создания стра ниц Ч исполняемых шаблонов, создающих возвращаемый браузеру HTML код. Но это только один из множества вариантов использования HTTP конвейера Ч базовой инфраструктуры ASP.NET. Конвейер Ч это универ сальная среда для на серверной служа щая базисом для страниц ASP.NET и Web-сервисов. Чтобы считаться се рьезным вы должны понимать, как работает этот Публиковалось в MSDN Magazine/Русская Редакция. 2002. № 3 (сентябрь). Ч Прим. изд.

Безопасная реализация запросов, фильтрации и переадресации конвейер. В нашей статье объясняется, как HTTP-конвейер обрабатывает запросы.

Объектная модель Типы, определенные в пространстве имен обрабатывают HTTP-запросы, используя конвейерную модель. Общая структура конвей ера показана на рис. 1. HTTP-запросы передаются экземпляру класса являющемуся входной точкой конвейера. Объект Http анализирует запрос и определяет, какому приложению он пред назначен (с точки зрения конвейера, приложение Ч это виртуальный ка талог). Затем, используя объект Factory, конвейер находит или создает объект HttpApplication, обрабатывающий запрос. HttpAppli хранит набор объектов Ч HTTP-модулей, реализующих интерфейс HTTP-модули это фильтры, анализирующие и изменяю щие содержание HTTP-запросов и ответов при прохождении последних по конвейеру. Используя фабрику HTTP-обработчиков (HTTP handler factory), объект HttpApplication создает или находит объект HTTP-обра ботчика. находятся на выходе из конвейера, и имен но они обрабатывают запросы и генерируют соответствующие ответы. Они реализуют интерфейс IHttpHandler, а фабрики реализуют интерфейс модули и обработчик используются для обработки только одного запроса единовременно. Если одновременно поступает не сколько запросов к одному и тому же приложению, используется и не сколько объектов HttpApplication. Для большей эффективности HttpApp и Http Factory поддерживают пул объектов Http Application и пул HTTP-обработчиков соответственно.

Каждой паре в конвейере соответствует объект HttpCon text. Этот объект передается в который в свою очередь передает его обработчику. Кроме того, каждый модуль может обращаться к текущему HttpContext. Объект содержит свойства, в кото рых в экземплярах классов и HttpResponse хранятся HTTP запросы и ответы. Объект HttpContext также предоставляет свойства, хра нящие информацию о защите и состояниях соединения, сеанса и приложе ния. В табл. 1 приведены наиболее интересные свойства класса Http Context.

HTTP-конвейер в ASP.NET полностью расширяемый. Вы можете реализо вать собственные HTTP-модули, обработчики и фабрики обработчиков и расширять функциональность класса HttpApplication.

ASP.NET Рис. 1. Обработка на HTTP-конвейере Табл. 1. Интересные свойства Свойство Описание Application Состояние приложения, сохраняемое между запросами Application Instance Объект Application, обрабатывающий запрос Cache состояние приложения Handler Объект-обработчик, обслуживающий запрос Items Состояние запроса Request HTTP-запрос Response HTTP-ответ Server Полезные функции Состояние приложения для данного пользователя, сохраняемое между запросами User Информация о пользователе Модель конвейерной обработки В ASP.NET HTTP-конвейеры принимают обрабатываемые запросы от Microsoft Internet Information Services (IIS) (но их можно интегрировать и с другим Web-сервером). Когда IIS получает HTTP-запрос, он анализи рует переданное в нем расширение файла. Если расширение связано с ис полняемым кодом, IIS вызывает этот код для обработки запроса. Соответ ствия расширений исполняемому коду хранятся в метабазе IIS. Во время установки ASP.NET в метабазу добавляются записи, соответствующие стандартным расширениям файлов, в том числе и связанные с библиотекой Когда IIS получает запрос на файл с этим расширением или он вызывает код из который в свою очередь направляет запрос HTTP-конвейеру. Запрос из службы IIS в которой реализация обработки и переадресации выполняется экземпляру рабочего процесса ASP.NET (aspnet_wp.exe) переадресуется через именованный канал. [В Windows Server 2003 ASP.NET интегрирована с HTTP-слушателем (listener) работающим в режиме ядра, что позволяет передавать запросы от ОС на прямую рабочему процессу, минуя Для обработки запроса рабочий процесс использует экземпляр класса На рис. показана общая архитектура конвейерной обработки.

. именованный канал Рис. 2. Архитектура конвейера в ASP.NET HTTP-конвейеры всегда обрабатывают запросы в экземпляре рабочего процесса. По умолчанию единовременно используется только один рабо чий процесс. (Если на компьютере несколько процессоров, можно настро ить конвейер на использование нескольких рабочих процессов Ч по одно му на каждый процессор.) Это заметное изменение по сравнению с род ной IIS, где для изоляции приложений друг от друга используется несколько рабочих процессов. В рабочем процессе конвейера изоляция осуществляется за счет применения Вы можете считать AppDomain своеобразным процессом внутри процесса. Все HTTP-запро сы к одному виртуальному каталогу пересылаются конвейером одному AppDomain. Другими словами, каждый виртуальный каталог рассматрива ется как приложение. Это еще одно заметное изменение по сравнению с IIS, в которой несколько виртуальных каталогов могли принадлежать одному приложению.

В ASP.NET поддерживается рабочих процессов в сти от нескольких критериев, в том числе от времени работы процесса, времени его простоя, количества обслуженных запросов, числа запросов, поставленных в очередь, и общего объема занимаемой памяти. Пороговые значения этих величин настраиваются в главном конфигурационном фай ле Ч machine.config (см. элемент processModel). Как только для эк земпляра превышается какое-либо из этих значений, asp запускает новый экземпляр рабочего процесса и начинает посылать ему запросы. Когда старый процесс заканчивает обработку зап росов в очереди, он завершается. Деактивизация рабочих процессов повы шает так как процессы завершаются до того, как их про изводительность ухудшится вследствие утечки ресурсов или других про блем при выполнении.

190 Microsoft HTTP-обработчики Ч просто классы, реализующие интерфейс как показано в следующем фрагменте кода:

interface // Вызывается для обработки запроса и формирования ответа void ctx);

// чтобы выяснить, ли обработчик // повторно { get;

} } Если нужно, чтобы обработчик поддерживал асинхронные вызовы, он дол жен реализовать интерфейс Объект вызывает метод когда ему требу ется, чтобы обработчик обработал текущий HTTP-запрос и сформировал ответ. Свойство определяет, может ли обработчик использо ваться более одного раза.

Код на рис. 3 реализует простой повторно используемый HTTP-обработ чик, в ответ на любой запрос возвращающий текущее время в XML-тэге.

Обратите внимание: для вывода ответа и указания его приме няется свойство Response объекта HttpContext.

Реализовав класс вы должны его развернуть. Развер тывание осуществляется в три этапа. Во-первых, нужно поместить ском пилированный код туда, где рабочий процесс ASP.NET сможет его обна ружить. В принципе это означает, что скомпилированная сборка (обычно DLL) помещается в подкаталог bin виртуального каталога ваше го сервера или в кэш глобальных сборок (Global Assembly Cache, GAC).

Затем нужно указать HTTP-конвейеру, что по приходу HTTP-запроса, отвечающего неким базовые критериям, следует исполнять ваш код. Для этого добавьте раздел в файл в вашем вирту альном каталоге:

/> безопасная запросов, и переадресации Эти данные рассматриваются как добавление к заданной в глобальном файле Ч В нашем примере файл fig сообщает HTTP-конвейеру ASP.NET, что HTTP-запросы GET на фай лы следует выполнять, вызывая класс из сбор ки Pipeline.

И, наконец, необходимо заставить IIS направлять запросы на файлы библиотеке чтобы та переправляла их конвейеру. Для это го добавьте в метабазу IIS новое сопоставление файлов, Это легче всего сделать через консоль управления IIS, в которой на вкладке Mappings ди алогового окна Application Configuration приведены сопоставления расши рениям файлов (рис. 4).

Помимо реализации собственных обработчиков, можно создавать свои фабрики обработчиков. Фабрика обработчиков Ч это реализующий интерфейс Фабрики обработчиков развертываются так же, как и сами обработчики;

единственное отличие в том, что элемент в файле относится к классу фабрики, а не к классу обработчи ка, создаваемого фабрикой. При реализации пользовательского HTTP-об работчика без реализации фабрики обработчиков используется создавае мый конвейером экземпляр стандартного класса Рис. 3.

using public :

{ С * "text/ml";

ctx.

tool { true;

GET.HEA -j Х.-!- GET HEA.

GET.HEA.

GET HEA Рис. 4. Добавление нового сопоставления Стандартные обработчики Высокоуровневые технологии ASP.NET, а именно страницы и Web-серви сы, являются надстройкой над Если взглянуть на глобальный файл можно увидеть следующие элемен ты /> /> /> Первый элемент сопоставляет расширение.ashx классу SimpleHandler Ч фабрике HTTP-обработчиков, умеющей компилировать и созда вать экземпляр класса, реализующего IHttpHandler из исходного кода в ASHX-файле. Получившийся объект напрямую используется НТТР-кон вейером.

Безопасная запросов, и переадресации На рис. 5 приведен пример переписанный в виде ASHX файла. Директива сообщает имя клас са HTTP-обработчика, экземпляр которого следует создать после компи ляции исходного кода. Такой подход облегчает развертывание: все, что нужно сделать, Ч скопировать ASHX-файл в виртуальный каталог. Созда вать или изменять файл или обновлять IIS не требуется Ч не обходимая настройка уже произведена при установке Второй элемент сопоставляет расширение.aspx классу Page Factory Ч фабрике умеющей компили ровать исходный код в ASPX-файле в класс, производный от Web.UI.Page и создавать его экземпляр. Класс Page реализует интерфейс поэтому получившийся объект напрямую используется Р Третий элемент сопоставляет расширение классу Web Service Ч фабрике HTTP-обработчиков, умеющий компилировать ис ходный код в класс и создавать экземпляр этого класса. За тем она лобертывает объект в экземпляр стандартного HTTP-обработчи ка (по умолчанию SyncSessionlessHandler), использующего механизм отра жения (reflection) для трансляции SOAP-сообщений в вызовы методов.

Опять же, получившийся объект напрямую используется НТТР-кон вейером.

Имейте в виду, что классы Page Handler Factory, Factory и SimpleHandlerFactory не компилируют ASPX-, ASMX- и по каждому запросу. Вместо этого скомпилированный код в подкаталоге Temporary ASPNET Files установочного каталога Код перекомпилируется только при изменении соответствующих исходных файлов.

Рис. 5. в виде ttabBandler using namespace Pipeline i>

7- ASP.NET Рис. 5. в виде // Установить flesportse. ToSt { } Рис. 6. Простой using namespace public>

i start;

public void app) { // new public void DisposeC) public o, // Записать начала запроса public void o, EventArgs // Измерить время = start;

// к контексту app = o;

ctx = к HTTP-ответу ctx.

обработки фильтрации переадресации HTTP-модули HTTP-обработчики Ч последнее звено в конвейере. Экземпляры классов HTTP-обработчиков выдают HTTP-ответы на HTTP-запросы.

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

HTTP-модули Ч просто классы, реализующие интерфейс interface IHttpModule { // Вызывается для подключения модуля к событиям приложения void Init(HttpApplication // Вызывается для очистки void Метод вызывается объектом HttpApplication при создании модуля.

Модуль может воспользоваться этой возможностью и подключить один или несколько обработчиков к событиям, генерируемым объектом Http Application.

Код на 6 реализует простой HTTP-модуль, обрабатывающий события BeginRequest и EndRequest объекта HttpApplication и вычисляющий вре мя, прошедшее между ними. В этом примере в методе Init стандартным для образом обработчики событий связываются с событиями, гене рируемыми объектом HttpApplication, к которому прикреплен модуль.

При обработке события BeginRequest в переменной-члене starts сохраня ется время генерации события. Обработка события EndRequest заключа ется в вычислении времени, прошедшего с момента события BeginRequest, и в добавлении этой информации к ответу в пользовательском HTTP-за головке.

Метод OnEndRequest пользуется тем, что в обработчик события первым параметром передается ссылка на объект, вызвавший событие (в нашем случае Ч на объект HttpApplication, к которому прикреплен модуль).

Объект HttpApplication предоставляет объект HttpContext для текущего сеанса запроса/ответа в виде свойства, и именно поэтому OnEndRequest может манипулировать HTTP-ответом.

После того как класс HTTP-модуля реализован, его необходимо развер нуть. Развертывание выполняется в два этапа. Как и в случае с HTTP-об работчиком, скомпилированный код модуля надо поместить либо в подка 196 Microsoft ASP.NET bin виртуального каталога Web-сервера, либо в чтобы рабочий процесс ASP.NET мог найти модуль.

Затем необходимо заставить HTTP-конвейер вызывать ваш модуль при каждом создании нового объекта обрабатывающего зап росы к вашему приложению. Для этого добавьте раздел в файл виртуального каталога Pipeline" /> Здесь в файле Web.config содержатся указания прикреп лять экземпляр класса к каждому объекту HttpApplication, созданному для обслуживания запросов к этому вирту альному каталогу.

Модель событий конвейера ElapsedTimeModule из предыдущего примера реализовал два обработчика событий: Begin Request и При обработке HTTP-сообще ний объект HttpApplication генерирует и другие события. Полный список событий приведен в табл. 2. Обратите внимание: объект ка, используемый экземпляром класса HttpApplication для окончательной обработки создается между событиями и Состояние сеанса пользователя (если оно существу ет) определяется во время события Acquire RequestState. И, наконец, обра тите что обработчик вызывается между событиями HandlerExecute и PostRequestHandlerExecute.

Все эти события класса HttpApplication доступны через многоадресные делегаты (multicast поэтому к каждому из них могут подклю чаться несколько HTTP-модулей. HTTP-модули могут регистрировать обработчики для любого числа событий своего объекта HttpApplication.

Однако с точки зрения эффективности модули должны регистрировать как можно меньше обработчиков.

Так как объект HttpApplication и его модули используются для обработки только одного HTTP-запроса единовременно, объекты HTTP-модулей реализация обработки запросов, фильтрации и переадресации могут сохранять между событиями любую необходимую информацию о состоянии запроса.

Иногда HTTP-модулю нужно влиять на обработку в конвейере. К приме ру, модулю, реализующему систему защиты, может потребоваться пре рвать нормальную обработку и переадресовать клиент на URL страницы регистрации (если он обнаружит, что запрос не содержит cookie, иденти фицирующий пользователя). Объект HttpApplication содержит метод Когда обработчик событий HTTP-модуля вызывает обычная обработка на конвейере преры вается после завершения текущего события (его обработки всеми други ми зарегистрированными обработчиками). Ожидается, что модуль, пре рвавший нормальную обработку запроса, сформирует соответствующий На рис. 7 приведен пример использующего CompieteRequest для прерывания нормальной обработки вызова Web-сервиса. Согласно специ фикации SOAP, HTTP-связывание (HTTP binding) требует, чтобы HTTP запрос, содержащий имел пользовательский заголовок SOAPAction. Обработчик события класса анализирует запрос и, если такой заголовок есть, а стати ческое поле enabled равно false, останавливает дальнейшую обработку.

Рис. 7. Остановка обработки System;

using Pipeline { public>

Рис. 7. Остановка обработки if return;

I // по запрос app HttpContext ctx s if null) // Если Web-сервисы // прервать обработку 403;

"Forbidden";

На рис. 8 приведен исходный код HTTP-обработчика который при каждом вызове своего метода пере ключает состояние статического поля enabled класса Module.

Рис. 8. er Pipeline public>

public I // и новое в enabled ! finableWeb^rviceuHodule.

ctx. Services " см. след. стр.

Безопасная запросов, фильтрации и переадресации Рис. 8.

?

public { что исходный код HTTP-модуля и скомпилирован в сборку Pipeline. Тогда для их настройки добавьте в файл строки:

Pipeline" />

Существует еще один важный момент, связанный с HTTP-модулями и методом Если модуль прерывает нор мальную обработку запроса во время обработки события, вызвав Сотр HTTP-конвейер прерывает обработку по завершении этого события. Однако EndRequest и последующие события все равно вызыва ются. Таким образом, модули, захватившие ценные ресурсы до окончания обработки, имеют возможность освободить эти ресурсы. К примеру, мо дуль, захвативший общее состояние (shared state) в обработчике события BeginRequest, может освободить его в обработчике EndRequest. Событие EndRequest вызывается, даже если другой модуль вызовет Complete Request и HTTP-запрос никогда не будет передан обработчику.

Табл. 2. События вызываемые объектами Событие Когда генерируется;

BeginRequest До начала обработки Для аутентификации клиента AuthorizeRequest Для проверки прав доступа Для получения ответа из кэша Acquire Request State Для загрузки состояния сеанса До отправки запроса обработчику После отправки запроса обработчику Для сохранения состояния сеанса Для обновления кэша ответа EndRequest По окончании обработки Send Request Headers До отправки заголовка ответа Content До буферизированной отправки тела ответа HTTP-приложения Как уже говорилось, HTTP-конвейер ASP.NET рассматривает каждый виртуальный каталог как приложение. По приходу запроса на конк ретного виртуального каталога, объект осуществляющий диспетчеризацию запроса с помощью объекта Factory, со здает или находит объект HttpApplication, обрабатывающий запрос. Дан ный объект HttpApplication используется только для обслуживания зап роса к единственному виртуальному каталогу, но для одного виртуально го каталога может существовать несколько экземпляров HttpApplication.

При желании можно изменить поведение класса HttpApplication для при ложения (виртуального Для этого нужно создать файл bal.asax. Если HTTP-конвейер обнаруживает в виртуальном каталоге файл он компилирует этот файл в класс, производный от Http Application. После этого конвейер создает экземпляр этого класса и ис пользует его для обслуживания запросов.

Наиболее интересный вариант использования файла global.asax Ч реали зовать класс, который обрабатывает события, вызываемые HTTP-конвей ером. Эти события делятся на две категории, первую из которых мы уже рассмотрели. Во-первых, в файле global.asax можно реализовать обработ чики для событий, вызываемых самим объектом HttpApplication (табл. 2).

Обычно эти события обрабатываются HTTP-модулями, но иногда нет не обходимости создавать и развертывать модули Ч особенно, если вам тре буется реализовать специфичное для приложения поведение.

Безопасная реализация обработки запросов, фильтрации и Например, в файле можно реализовать обработчик для события BeginRequest:

import Этот код к новому от HttpApplication В этом примере обработчик события по нали чию заголовка SOAPAction определяет вызов Web-сервиса. Вызов SOAP регистрируется в свойстве Items текущего объекта HttpContext (доступно го как свойство HttpApplication Ч предка нашего класса). Свойство Items используется для хранения информации о состояния запроса, необходи мой другим модулям и финальному обработчику запросов. Оно очищает ся после завершения запроса. HTTP-модуль может обеспечить такое по ведение, но для единственного приложения его проще реализовать таким образом. (Наш класс, производный от HttpApplication и обрабатывающий события от базового класса, может показаться странным, но такой класс весьма удобен!) Два дополнительных события уровня приложения не приведены в табл. и обычно недоступны HTTP-модулям. Это события Start и знакомые программистам на ASP.

Они вызываются при первом обращении к приложению и при завершении его работы соответственно. Вот простой пример:, public void { // здесь приложение } public void { выполняется очистка } 202 Microsoft К другой категории событий, обрабатываемых классом, производным от относятся вызываемые HTTP-модулями. На самом деле именно так конвейер реализует события ASP и Оба эти события вызываются классом Вернемся к ранее рассмотренному который от клонял вызов Web-сервиса в зависимости от состояния своего статическо го поля. При отклонении запроса он формировал короткое, в код сообщение. Лучше, если бы модуль позволял приложению самому формировать сообщение. Один из способов сделать это Ч заставить HTTP модуль генерировать событие при отклонении запроса к Web-сервису. На рис. 9 приведен код новой версии вызывающей событие Rejection при запроса к Web-сервису. В новой версии обработчик события проверяет, зарегистрирован ли обра ботчик события Rejection, сравнивая значение в свойстве с null. Если об работчик для этого события зарегистрирован, модуль вызывает событие.

При этом предполагается, что обработчик сформирует соответствующий HTTP-ответ. Если обработчики не зарегистрированы, модуль самостоя тельно формирует короткий HTTP-ответ.

Рис. 9, Вызов события using System;

using public :

{ // Событие // Поле, = trye:

public app) // public void public void ea) // Если включены, // дальше в см. след. стр.

Безопасная обработки запросов, и переадресации Рис. 9. Вызов события Rejection (enabled) // // ли арр = obj;

if (э Ч // и запрос Reque // зарегистрировало обработчик // его, чтобы обработчик // иначе ответ if i else = 403;

= "Forbidden";

Чтобы приложение обрабатывало вызываемые модулем события, в нем просто реализуется соответственно названный метод. Схема именования основана на имени, присвоенном HTTP-модулю в файле при развертывании модуля, и имени события, вызываемого модулем. В преды дущем примере модуль называется (класс име ет то же имя, но это просто совпадение), а событие называется Rejection.

Соответственно прототип обработчика этого события таков:

public void o, EventsArgs ea);

Бот его реализация:

import ASP.NET public object o, EventArgs ea) { = 403;

= = "text/plain";

web + not available now, + "please try your request } Конвейер самостоятельно связывает правильно именованный обработчик и событие. Теперь HTTP-модуль, отклоняющий вызов вызы вает событие Reject, и приложение имеет возможность сформировать бо лее понятное сообщение. Новая архитектура приведена на рис. 10 полно стью, включая обработчик, управляющий поведением модуля.

Обрабатываются не Запросы всегда Класс HTTP Переключить флаг enabled Событие Rejection Рис. 10. Архитектура Защита в конвейере Очень часто в HTTP-модулях прозрачно для приложения реализуются защитные функции вроде авторизации и аутентификации. Взгляните на список по умолчанию установленных для Web-приложе ний в файле (для краткости имена типов опущены):

odd Помимо модулей кэширования выходных данных и модулей управления состоянием, остальные модули предназначены для облегчения реализации Безопасная реализация обработки и переадресации защиты. Обратите внимание: порядок модулей имеет значение. Если аутен тификация отвечает на вопрос Ты то авторизация Ч на вопрос А тебе это Очевидно, что аутентификация должна происходить до авторизации, поэтому модули расположены в таком порядке.

Три модуля соответствуют трем режимам аутенти фикации в файле При выборе любого способа аутентификации (кроме None) начинает ра ботать соответствующий модуль. Задача таких модулей состоит в обмене аутентификационными данными с клиентом и, возможно, с доверяемым центром сертификации вроде После аутентификации эти модули создают реализации и IPrincipal, которые используются для принятия решения о разрешении или отклонении запроса. Эти реше ния принимаются авторизационными модулями, расположенными далее по конвейера. Сведения об авторизации хранятся в свойстве Http Context.User. в конце конвейера тоже может обращать ся к этим сведениям.

Допустим, файл web.config выглядит так:

Модуль первым обрабатывает запрос и обнаружива ет, что клиент не послал специального cookie, соответствующего ранее проведенной успешной регистрации. Тогда модуль создает объект Ilden tity, указывающий, что пользователь анонимный, и объект свя зывающий пустой список ролей с этой идентификацией, после чего связы вает IPrincipal со свойством Модуль UrlAuthorization получает запрос и обнаруживает, что в файле web.config запрещен аноним ный доступ к этому каталогу. Тэг запрещает анонимный доступ. Модуль проверяет пользователя, связанного с текущим контек стом через свойство выясняет, что пользователь Microsoft мен, и прерывает запрос, указывая, что доступ запрещен. Но это еще не конец. Authentication Module обнаруживает, что запрещенный запрос отослан обратно клиенту, видит, что пользователь не и изменяет ответ, перенаправляя пользователя на Ч страницу реги страции по умолчанию.

Если пользователь отправляет странице регистрации правильные учетные данные, обработчик страницы регистрации вызывает Page, а эта функция переадресует клиент на перво начально запрошенную страницу и посылает ему зашифрованный cookie, содержащий имя пользователя. После того как пе реадресованный клиент вновь запрашивает исходную страницу, модуль дешифрует и проверяет а затем создает tity с именем пользователя. Эта идентификация связывается с пустым списком ролей и сопоставляется с Ранее мы об этом не упоминали, но после настройки HttpContext.User модуль FormsAuthentication вызывает событие При реализации обработчика этого события в файле global.asax вы можете пользоваться созданным модулем и связать его со списком определенных приложением ролей. Такой пример приведен на рис. 11.

Рис. 11. Обработчик AuthenticateRequest public identity if roles * I // Для краткости поиск в базе опущен По окончании работы FormsAuthentication наступает очередь Он обнаруживает, что запрос авторизован, т. е. требова Безопасная реализация обработки и переадресации ния первой строки раздела соблюдены. он проверя ет, входит ли пользователь в группы Manager или Staff. Если да, запрос будет принят, иначе последняя строка раздела приведет к отклонению запроса. В этих строках символ подстановки ? означает неау запросы, а символ подстановки * Ч все запросы.

Этот пример показывает, как HTTP-конвейер позволяет без особых уси лий добавлять защиту (особенно авторизацию и аутентификацию) в са мые разнообразные Web-приложения.

Заключение В этой статье рассказывалось о HTTP-конвейерах, гибкой инфраструкту ре для HTTP-программирования на серверной стороне. Интегрированный с IIS HTTP-конвейер предлагает богатую модель программирования, ба зирующуюся на приложениях, модулях и обработчиках, которые вы при желании можете реализовать самостоятельно. Недостаток места не позво ляет рассказать обо всех важных аспектах в том числе о поддержке управления состоянием, Ч эта тема заслуживает отдельной ста тьи. Надеемся, что наша статья поможет вам лучше понять работу HTTP конвейера и его применение в HTTP-приложениях Исходный код для этой статьи можно скачать по ссылке в разделе за сентябрь.

Тим Эвалд (Tim Ч менеджер программы (Program Manager) в группе XML Web Services в Microsoft. Работает над спецификациями Web-сервисов и API-функциями, а также распространяет информацию для разработчиков.

Автор книги Building Scalable Applications (Addison Wesley, 2001). С ним можно связаться по адресу tewald@microsoft.com.

Кит Браун (Keith Brown) работает в как технический писатель и Разъясняет программистам концеп ции безопасного кода. Автор книги Programming Windows Security (Addlson Wesley, 2000), соавтор Effective COM. С ним можно связаться через сайт Джордж Шеферд ASP Развертывание с помощью Visual Studio В этой статье поясняется, что нужно сделать для развертывания ASP.NET приложений, созданных в Visual Studio Разработка Web-приложений в Visual Studio практически не отличается от разработки персональных приложений. Однако создается множество вспомогательных файлов, необходимых при разработке, но не нужных для развертывания. Поэтому автор на примере файлы следует включать в установоч ный пакет, а какие Ч нет.

Многие новшества Visual Studio облегчают создание Web-приложе ний. Microsoft Framework включает классы для перехвата и обработ ки HTTP-запросов, a Visual Studio Ч средства проектирования ин терактивных пользовательских HTML-интерфейсов. По сути, разработка в Visual Studio не сложнее создания обычного пер сонального приложения. Кроме того, по-видимому, Ч самый простой способ быстро создать и запустить Web-сервис.

Хотя информации о большинстве этапов разработки ASP.NET-приложе ний, в том числе об архитектуре и приемах программирования, довольно много, сведения о развертывании таких приложений найти трудно. В этой статье я объясню, что нужно для развертывания ASP.NET-прило жений, созданных в Visual Studio Публиковалось в MSDN Magazine/Русская Редакция. 2002. № 5 (ноябрь). Ч Прим. изд.

Развертывание с помощью File I New I Project Почти любая программа, созданная в Visual Studio начинается с меню File New Project. Если вы уже давно работаете с Visual Basic или Visual C++, то скорее всего знаете, какие файлы генерируются при созда нии нового проекта. Это отнюдь не только файлы исходного кода Ч кро ме них создается множество других, в том числе файлы рабочей среды (workspace files), проекта, ресурсов, make-файлы и т. д.

Как и предыдущие версии, Visual Studio генерирует умопомрачи тельное множество файлов. При развертывании приложения (особенно приложения ASP.NET), созданного в Visual Studio не ясно, какие части исходного кода нужно включать в установочный пакет. Например, отделить код, отвечающий за программную от кода пользователь ского интерфейса нетрудно благодаря поддержке в ASP.NET отделен ного кода (code-behind). Но иногда сделать это совсем не просто. к могли быть добавлены блоки серверного сценария (на С# или Visual Basic). Хотя для развертывания приложения исходный код на С# или Visual Basic не нужен, вам понадобятся (Web-фор мы), которые тоже могут содержать код. Это же относится к файлам типа ASCX (пользовательские элементы управления), (реализации Web-сервисов) и ASHX (обработчики). Кроме того, Visual Studio создает файлы проектов и решений. И когда дело доходит до развертывания ASP.NET-приложений, вопрос о том, какие файлы вклю чать, а какие Ч нет, становится серьезным.

Посмотрим, какие именно файлы генерирует Visual Studio и где они находятся в дереве каталогов.

Структура каталогов по умолчанию Когда вы открываете новый проект, Visual Studio создает структуру каталогов по умолчанию. В предыдущих версиях Visual Studio файлы про екта обычно помещались в один каталог, нередко содержащий несколько подкаталогов (например, среда Visual Studio 6.0 создавала подкаталог В случае ASP.NET структура каталогов, формируемых Visual Studio весьма изощренна.

Во-первых, так как приложения ASP.NET предназначены для работы в Web, они подчиняются ограничениям Microsoft Internet Information Ser vices (IIS). To есть этим приложениям нужны виртуальные каталоги. Ма стер ASP.NET-приложений Web Forms создает виртуальный каталог при создании приложения. По умолчанию Visual Studio помещает боль шинство файлов приложения в один из подкаталогов каталога wwwroot.

Скажем, если вы создадите в Visual Studio ASP.NET-приложение AppDuJour, в wwwroot автоматически будет сформирована такая структу ра каталогов;

210 ASP.NET INetPub \bin AppDuJour.

Этот физический каталог отображается на виртуальный каталог AppDu Jour в IIS. После сборки приложение можно запустить из Visual Studio или обратиться к нему через виртуальный каталог AppDuJour.

По умолчанию Visual Studio помещает файл решения (AppDuJour. SLN) в подкаталог AppDuJour каталога Documents and Settings. Такой файл аналогичен файлу рабочей среды и используется для управления проектом (или проектами). Структура каталога выглядит так:

and Settings Visual Studio Projects AppDuJour Если вы хотите сменить каталог по умолчанию для файла решения, сме ните каталог по умолчанию для проекта до его создания. Откройте Tools Options и выберите Projects and Solutions в режиме Environment.

Наконец, Visual Studio добавляет подкаталог к каталогу VSWeb Cache, например:

Documents and Settings GeorgeShepherd AppDuJour Project Кэш Web-проекта Visual Studio облегчает автономную разработку. (Я рассмотрю ее чуть позже.) Если вы решили использовать Visual Studio для разработки приложения на удаленном Web-сервере, то на время разработ ки ваши файлы будут храниться на локальной машине.

Visual Studio создает массу новых файлов и каталогов на диске. Чтобы знать, где что искать, надо понимать их структуру. Кроме вы, возмож но, захотите изменить расположение этих файлов.

Развертывание с помощью Visual Studio Использование других каталогов Хотя отлично подходит для хранения вашего Web-сайта, вы вряд ли захотите разрабатывать приложение в этом каталоге (я, так, точно). Но назначить исходному коду вашего приложения другой каталог очень легко.

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

Затем отобразите его на виртуальный тоже на AppDuJour).

При создании проекта в Visual Studio мастер предлагает ввести путь к виртуальному каталогу на вашем компьютере (по умолчанию Ч Чтобы переименовать приложение (если только вам действительно не нравится и поместить его исходные файлы в каталог AppDuJour, просто введите host/AppDuJour в поле Location.

Удаленное создание проекта Другой вариант Ч создать приложение Web Forms на удаленном сервере.

Если назначить проекту сервер в Интернете (скажем, NightHosts.com/AppDuJour), Visual Studio создаст проект именно на этом сервере Ч конечно, при условии, что у вас есть необходимые разрешения.

Для этого на сервере надо активизировать расширения FrontPage (Front Page extensions). Тогда Visual Studio поместит файлы проекта в подката лог VSWebCache и будет синхронизировать файлы между сервером и ком пьютером, на котором ведется разработка. Чтобы активизировать расши рения FrontPage, выберите Tools | Options Web Settings. После этого мож но включить File Sharing или расширения FrontPage. Параметры режима доступа к Web на странице свойств проекта показаны на рис.

Рис. 1. Параметры режима доступа к Web 212 Microsoft ASP.NET Если Web-сервер находится в вашей сети и у вас есть к нему доступ, про ект можно открыть по UNC-пути. Для этого включите режим совместно го использования файлов (file sharing) в виртуальном каталоге. Visual Studio создает файл решения на локальном компьютере, и этот файл ссы лается на удаленный сервер. При этом Visual Studio управляет файлами приложения, синхронизируя их между локальным компьютером и Web сервером. Для управления онлайновым статусом приложения используй те Project Web Project. Это же меню позволяет синхронизировать каталоги.

Модель выполнения в Для эффективного развертывания приложения и отбора нужных файлов важно понимать модель в ASP.NET. Вспомните, что ASP.NET поддерживает отделенный код, т. е. прикладную логику и презентацион ный код можно хранить в разных файлах. Более по умолчанию Visual Studio даже навязывает такое разделение. каждому ASPX-фай лу соответствует файл с исходным кодом на С# или Visual Basic Visual Studio связывает ASPX-страницу и страницу с отделенным кодом, включая в ASPX-файл директиву Codebehind:

Раде Файлы приложения ASP.NET (в нашем случае Ч ASPX-файл) хранятся в виртуальном каталоге Web-приложения. Когда вы впервые обращаетесь к ASPX-файлу через Web (или если какой-нибудь из файлов был изменен с момента последнего обращения), ASP.NET компилирует файлы приложе ния (исходный код и файл созданный при сборке проекта) в сборку (assembly). Затем ASP.NET копирует эту сборку (и другие ком поненты, от которых зависит приложение) во временный каталог и запус кает сайт. Если вы понимаете, как ASP.NET настраивает исполняющую среду, вы легко какие файлы нужно включить в установочный пакет. Вскоре я перечислю все необходимые файлы. Вы можете выбрать либо проект развертывания (deployment либо развертывание вручную (manual deployment). Начнем с проектов, Проекты развертывания Модель развертывания Web-приложений отличается от модели разверты вания персональных приложений. Обычно Web-приложения часто обнов ляются. Но управлять приложениями в куда чем компонен тами в СОМ.

Одна из наиболее важных целей компонентной модели Ч облегчить установку компонентов. Так, управлять сложными Web-приложениями, написанными на классическом ASP, довольно трудно, поскольку для это с помощью Visual го надо управлять А установка Ч процесс трудоемкий, так как приходиться вносить изменения в реестр и при этом проверять, не повлияли ли эти изменения на другие приложения на сервере. Компонентная модель гораздо проще, потому что в предпочтение отдается не а закрытым компонентам, благодаря чему для установки большинства приложений достаточно скопировать их файлы такой утилитой, как XCOPY. В результате вы просто собираете все файлы приложения воедино. Эту задачу можно возложить на программу установки, которая создается мастером Web Setup Project Wizard в Visual Studio. Мастер генерирует всю программу установки, которую достаточно запустить на любом сервере для развертывания на нем Web-приложения.

Вот как это работает.

Создавая проект Web Setup, вы обычно добавляете его к существующему проекту. Сначала выберите File Add Project New Project. Затем выбери те Setup and Deployment Projects. Откройте шаблон Web Setup Project. Тем самым вы добавите новый подпроект к файлу решения.

Создав проект Web Setup, Visual Studio предоставляет интерфейс в стиле Explorer для выбора файлов, включаемых в этот проект. После установки приложения Web Application Folder преобразуется в виртуальный каталог.

Для добавления файлов к установочному пакету щелкните правой кноп кой мыши Web Application Folder или другой каталог и выберите Add File. Чтобы добавить к проекту какую-нибудь глобальную сборку, выбери те Add Assembly. Добавляя компоненты из Global Assembly Cache, поль зуйтесь Component Selector. При включении сборки (скажем, Visual Studio добавляет и все зависимые сборки. Проект Web Setup с не сколькими добавленными файлами показан на рис. 2.

V ftppDuJourSelup - Microsoft Development I on command bin Рис. 2. Проект Web Setup с добавленными файлами Чтобы приложение могло работать на Web-сервере, необходимы файлы с расширениями.aspx,.ascx,.ashx и а также файл Кро ме того, вам потребуется содержимое каталога \bin (прежде всего сборка, созданная в процессе компиляции) и содержимое вспомогательных ката 214 Microsoft логов (например с изображениями). Не забудьте включить все нужные вашему приложению общие сборки (shared assemblies). Файлы исходного кода на С# или Visual Basic файлы проекта и ресурсов вам не пона добятся.

Включив файлы в проект Web выделите его в Solution Explorer и соберите. В результате вы получите файл Microsoft Install (MSI) и устано вочный файл.

Развертывание вручную Вы можете вручную развернуть проект, скопировав все необходимые фай лы на Web-сервер. Так как модель развертывания в подразумевает копирование всей структуры каталогов приложения, вы можете просто заархивировать каталог приложения со всеми его подкаталогами и разар на требуемом компьютере. Фактически это то же самое, что и создание проекта Web Setup, Ч только работы чуть больше.

Заключение В Visual Studio разработка Web-приложений практически не отлича ется от разработки персональных приложений. Такая функциональность, как серверные элементы управления и дизайнеры Web Forms, существен но облегчает создание приложения для распространения по HTTP с ис пользованием HTML. Однако, как и в предыдущих версиях средств визу альной разработки от Microsoft, создается множество вспомогательных файлов, необходимых при разработке, но не нужных для развертывания.

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

Джордж (George создает средства разработки для в SyncFusion. Преподает на курсах в и является автором целого ряда по программированию, в том числе Programming with Microsoft Visual (Microsoft Press, 2002) и Applied (Addison Wesley, 2001). С ним можно по адресу georges@syncfusion.com или georges@develop.com.

Дэвид Чеппел Новые технологии защиты надлежащей раскрыть их потенциал не WS-Security и с ней технологии, о которых пойдет речь в этой статье, Ч новое слово в Автор дает обзор новых безопасности, из которого вы поймете, что позволяют делать эти технологии, как они работают и Обсуждаются целостность и информации, способы их обеспечения путем шифрования с открытым ключом (public key cryptography), WS-Security и многое другое. Также рассказывается о некоторых ключевых WS-Security, в частности о пространстве имен Без эффективной защиты Web-сервисы практически бесполезны. Тем не менее создатели SOAP решили отложить определение стандартов обеспе чения безопасности. В то такое решение было оправданно: чтобы сдвинуть Web-сервисы с мертвой точки, их нельзя было усложнять, а за щита никогда не бывает Однако решение проблемы нельзя откла дывать и Microsoft совместно с IBM и другими компаниями сейчас работает над ней. Это привело к появлению серии спецификаций по обес печению безопасности Web-сервисов, важнейшей из которых является Данная статья представляет собой общий обзор WS-Security и связанных с ней Задача, стоящая перед создателями средств защиты Web-сервисов, кажет ся простой. Ведь уже есть эффективные механизмы обеспечения распре деленной защиты (например шифрование с открытым ключом и др.), так что нужно не придумывать новые способы защиты, а реализовать * Публиковалось в MSDN Magazine/Русская Редакция. 2003. № 4 (апрель). Ч Прим. изд.

Новые защиты Web-сервисов имеющиеся технологии в Web-сервисах Ч в мире, где царят и SOAP.

Существует несколько спецификаций по безопасности, в том числе следу ющие.

Х Ч основа остальных спецификаций Ч описывает расши рения SOAP, которые позволяют передавать маркеры защиты (security tokens) для безопасной идентификации и аутентификации клиентов, а также обеспечивают целостность и конфиденциальность сообщений.

Сопутствующая спецификация Web Services Security Addendum содер жит некоторые дополнения и исправления.

Х определяет правила безопасности Web-сервисов.

Х WS-Trust определяет порядок получения маркеров защиты.

Х описывает создание контекста для каждого взаимодействия с Web-сервисом и создание ключей для применения в данном контексте.

Х Web Services Security Profile XML-based Tokens порядок совместного использования WS-Security и XML-технологий, таких как SAML (Security Assertion Markup Language) и XrML (extensible rights Markup Language). Победитель в номинации За самое длинное назва ние Все вместе эти спецификации служат основой для выработки практично го и целостного подхода к обеспечению безопасности WS-Security определяет фундаментальную технологию защиты SOAP.

Несмотря на довольно амбициозную цель Ч обеспечить сквозную защиту Ч спецификация WS-Security не слишком объемна и занимает лишь около 20 страниц. Дело в что WS-Security содержит очень мало нововведений, преимущественно определяя способы примене ния в SOAP существующей технологии защиты.

важнейшая из определяемых в WS-Security сущностей элемент Security;

он размещается в На рис. 1 показана структура с этим элементом. Как видите, WS-Security определяет собственное пространство имен. Авторы WS Security придерживаются существующих стандартов и технологий, сосре доточившись на путях использования этих технологий совместно с SOAP.

WS-Security описывает способы достижения целостности (когда получа тель может быть уверен, что принятые им данные не изменялись при пе редаче) и конфиденциальности, гарантирующей защиту передаваемой ин формации от несанкционированного прочтения. Она также определяет порядок отправки маркеров защиты, например комбинации имени пользо вателя и пароля, билета Kerberos или сертификата Х.509. Об этом расска зывается в следующих разделах.

Рис, 1. Элемент Security /s:

Отправка маркеров защиты Получателя сообщения всегда беспокоит вопрос: с кем я разговариваю?

Вопрос простой, но ответить на него сложно. Способов идентификации в сети много (имя пользователя, билет Kerberos, сертификат Х.509 и т. п.), способов аутентификации этих данных Ч тоже. Например, имя пользова теля можно сопоставить с определенным паролем, что это имя действительно ваше. Билет Kerberos, напротив, шифруется отпра вителем с использованием ключа, достоверность которого можно прове рить при получении билета. А с сертификатом направляется цифровая подпись, подтверждающая личность отправителя (см. также врезку Что такое цифровая Авторы WS-Security разумно решили не полагаться на какой-то один спо соб передачи и подтверждения идентификации. В принципе WS-Security вообще не регламентирует способ аутентификации. Она лишь определяет способ передачи маркеров защиты в элементе Security заголовка SOAP.

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

Допуская любые типы маркеров защиты, спецификация WS-Security яв ным образом описывает три Простейший (хотя не всегда безо пасный) вариант Ч передача маркера защиты, содержащего имя пользова теля и пароль. Для этого в WS-Security определен элемент в котором они и размещаются. Вот пример элемента Security, содержаще го только UsernameToken:

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

Еще один вариант, описанный в Ч отправка маркера защиты с билетом Kerberos. Как и все маркеры защиты, билет передается в SOAP заголовке как часть элемента Security. Вот пример:

Как видите, билет передается при помощи более универсального элемента BinarySecurityToken. Его атрибут ValueType указывает на то, что передается билет сервиса Kerberos версии 5 (Kerberos Version 5 service ticket), который служит для аутентификации клиента определенным сер висом. (При отправке TGT атрибут ValueType содержит значение wsse:Ker beros v5TGT.) Сам билет (показаны только первые несколько байтов) ко дируется по основанию base64, хотя можно кодировать и в ричной форме.

из описанных в вариантов передачи маркеров защиты Ч сертификаты Х.509 Ч также использует элемент BinarySecurity Token. Пример:

220 Web-сервисы Как видите, он не сильно отличается от предыдущего примера с билетом Kerberos. В данном случае атрибут ValueType элемента Token> указывает на то, что передается сертификат Х.509. Здесь снова применяется кодирование по основанию base64, а сам сертификат, как и билет Kerberos из предыдущего примера, как содержимое эле мента.

Помимо этих способов, предусматривающих встраивание маркера защиты прямо в заголовок SOAP-сообщения, определяет элемент Token В нем задается который указывает, где нахо дится маркер Это позволяет получателю сообщения запросить маркер из любого места, например откуда-то из Интернета. При помощи этого элемента можно ссылаться на маркер защиты, включенный в заголо вок данного Зачем это нужно, станет ясно в следующем разделе.

WS-Security предлагает потрясающе гибкий подход к передаче и провер ке идентификаторов, который, однако, накладывает одно важное ограни чение: две системы, отвечающие требованиям WS-Security, могут оказать ся неспособными аутентифицировать друг друга. Так, одна система может поддерживать только Kerberos, другая Ч только аутентификацию с циф ровой подписью на основе сертификатов Х.509. Соответствия специфика ции WS-Security недостаточно Ч необходимо прийти и к соглашению по поводу использования конкретных типов маркеров защиты.

Целостность Передача и проверка идентификации в Ч проблема многогранная, из числа тех, которые можно решить разными способами.

Поэтому WS-Security предлагает подход, обладающий необходимой той. Однако обеспечить целостность гораздо Для этого требуется что-то вроде цифровой подписи, и, к уже есть соответствующий стандарт W3C, называемый XML Signature. Он предос тавляет механизм, при помощи которого создается цифровая подпись для XML-документов. Вместо изобретения того, что уже существует, WS Security просто ссылается на этот стандарт и уточняет некоторые детали его использования в SOAP-сообщениях.

Основной объект, определяемый в спецификации XML Signature, Ч эле мент Signature, который содержит саму цифровую подпись и информацию о способе ее создания. Есть несколько вариантов использования Signature, но в SOAP-сообщениях он обычно содержит элементы и Элемент Signedlnfo описывает информацию, для которой создавалась цифровая подпись. Он несколько вложенных элементов, каждый защиты из которых определяет какой-либо параметр подписываемой информации.

Вот важнейшие из них.

Х указывает алгоритм, по которому этот XML-до кумент приводился к стандартной форме перед созданием цифровой подписи. Такое преобразование необходимо потому, что для использо вания цифровой подписи требуется, чтобы представление XML-до кумента различными сторонами совпадало с точностью до бита. А без такой канонизации (canonicalization), два семантически идентичных XML-документа могут отличаться на битовом уровне. Так, в одном конец строки может обозначаться символами возврат каретки/пере вод а в другом Ч только символом перевода строки. Канони зация приводит XML-документ к стандартной форме, обеспечивая точное совпадение документов перед созданием цифровой подписи.

Х Signature Method указывает алгоритм, по которому создавалась цифро вая подпись. И XML Signature и WS-Security требуют соответствия стандарту Digital Signature Standard, согласно которому сообщение об рабатывается при алгоритма хэширования SHA-1 и алгорит ма DSA. Кроме того, рекомендуется поддержка совместного использо вания SHA-1 и RSA.

Х Reference описывает информацию, для которой применяется цифровая подпись, и указывает все преобразования, выполненные над этой ин формацией. При использовании в SOAP эта часть подписи обычно оп ределяет подписываемые участки SOAP-сообщения, такие как тело сообщения и фрагменты заголовка. Элемент Reference также содержит закодированный по основанию base64 хэш из подписанной информа ции и указание на алгоритм хэширования, например SHA-1.

Х Value содержит цифровую подпись.

Х указывает ключ, применяемый для проверки достоверности подписи. Ключ можно указать разными способами, например, сослав шись на сертификат, содержащий необходимый открытый ключ. Если получатель уже информирован о нужном ключе, этот элемент может отсутствовать. Теперь, когда у вас есть представление о структуре эле мента Signature, можно ознакомиться с примером его использования.

На рис. 2 показан фрагмент SOAP-сообщения с цифровой подписью.

В этом примере элемент Security в заголовке начинается с Security Token. Этот элемент практически идентичен примеру с сертификатом из предыдущего раздела. Единственное отличие Ч в использовании данным элементом атрибута Id, описанного в Web Services Security Adden dum и указывающего имя данного элемента нее об этом см. врезку Пространство имен Значение атрибута Id Web-сервисы (в данном случае может применяться для ссылок из любого места заголовка. Позже вы увидите, что это может пригодиться, если со общение содержит цифровую подпись.

Рис. 2. с подписью :

;

URI Новые технологии защиты Что такое цифровая подпись?

Как нечто с с ключом. Эта гая предполагает наличие пары ключей: который знаете только вы, и ему открытого ключа, который можно свободно кому При этом зашифро ванная посредством из может быть только с помощью Если надо подписать какую-то вначале для нее вычисля ется специальная контрольная сумма Ч Затем хзш, занимающий, как правило, около 20 байтов, шифруется с помощью закрытого В результате получается цифровая для данной информации.

достоверность, получатель с такой под писью, должен знать только открытый ключ При провер ке вычисляется хэш полученных а затем откры ключа расшифровывается Если результаты вы можете быть что не менялись при передаче (т. е. в их что они саны обладателем закрытого ключа Ра зумеется, нужно быть уверенным в достоверности открытого он может быть получен из сертификата от доверяемого по средника.

Таково классическое Но в кации XML Signature подразумевается несколько иное. Хотя стандарт допускает с открытым клю он также позволяет использовать (секретный) Такой подход, обеспечивая данных используется в не применить откры того ключа. Поскольку быть известен или более с его помощью данные могут быть любой из этих А такая подпись не позволяет точно Тем не менее это полезная функ и допускает секретного ключа наравне с цифровых Далее следует элемент Signature, описанный в стандарте XML Signature, который включает вложенные элементы SignatureValue и Элемент Signedlnfo содержит идентификаторы алгоритмов кано низации XML-документа и алгоритмов создания цифровой подписи. Эле мент Reference через атрибут URI указывает подписываемую информа цию, В нашем примере подписано только тело сообщения, поэтому URI совпадает со значением атрибута Id элемента Body. Элемент Reference и сам содержит два вложенных элемента: и Value. Пер вый определяет алгоритм хэширования сообщения, второй содержит сам хэш. Поскольку в примере подписывается только тело сообщения, хэш формировался на основе элемента Body из канонизированной версии Следующий вложенный в Signature элемент, содержит байты самой цифровой подписи, полученной путем шифрования хэширо ванного сообщения с использованием закрытого ключа (private key) от правителя. И, наконец, последний вложенный в Signature Key Info, показывает, где получить открытый ключ для проверки подписи.

В нашем примере этот ключ содержится в самом сообщении (в маркере за щиты) и указывается через ссылку в Token Reference. Сам ключ определяется значением атрибута Id.

Пространство имен В Web Services Security приводятся некоторые дополнения (в исправления) к спецификации Определен в этом документе новые XML-элементы представлены в и имеют префикс wsu. С важны два объекта из пространства имен.

вый Ч атрибут может быть к разным там. Согласно WS-Security он применяется в создании цифровых указываться в SOAP-сообщения. Он может содержать женные дату создания сообщения, его получе ния на промежуточных адресах и срок На основании получатель решает, не просрочено ли данное сообщение, отслеживает одинаковые сообщения т. д. Однако в стандартах не описан способ на разных щих в так что эту проблему решать не могут получиться безупречными с первого так что и исправлений к редакции вполне Целостность данных очень важна для многих Web-сервисов, поэтому на личие четко определенных универсальных правил ее обеспечения в SOAP приобретает огромное Кроме того, цифровые подписи с исполь зованием технологии открытого ключа позволяют аутентифицировать от правителя, так как предоставление достоверной подписи вместе с доверя емым сертификатом доказывает знание конкретного закрытого ключа, а значит, и личности его владельца. Но создать цифровую подпись для Новые технологии защиты XML-документа по-прежнему непросто. Вначале нужно четко определить подписываемую информацию, затем перевести ее в каноническую форму и только потом создавать саму подпись. Процесс может быть еще сложнее приведенного здесь примера, так как допускает наличие не скольких подписей в одном сообщении, созданных разными людьми в раз ное время и подтверждающими разные или даже перекрывающиеся обла сти сообщения. Следование стандарту XML Signature при создании таких подписей вполне оправданно, однако приводит к увеличению и ус ложнению заголовков SOAP-сообщений по сравнению с сообщениями, не использующими такой способ защиты.

Конфиденциальность Для многих приложений важно защищать данные от чужих глаз при пе редаче. Поэтому третьим из описанных в WS-Security аспектов является конфиденциальность, предусматривающая шифрование части или всего SOAP-сообщения перед отправкой. Авторы WS-Security решили не создавать новые инструменты, а основываться на существующих стандар тах. И вновь был выбран стандарт W3C Ч XML Encryption, который по зволяет полностью или частично зашифровывать заголовок SOAP-сооб щения, его тело и любые приложения. Стандарт XML Encryption доволь но прост. Например, в WS-Security используются всего три определяемых им XML-элемента: Encrypted и Разумеется, важнейший из них Ч Encrypted Data. Как следует из его ни, он содержит зашифрованные данные (во вложенном элементе Data). Кроме того, он может содержать вложенные определяю щие алгоритм шифрования, ключ и другие параметры. На рис. 3 показан пример простого SOAP-сообщения с зашифрованным телом.

Заметьте: в этом сообщении нет заголовка. Хотя это нечасто встречается в реальных приложениях, WS-Security допускает использование XML ryption без элемента Security и других элементов заголовка. В этом при мере тело сообщения содержит только элемент Encrypted Data с тремя вло женными элементами. Первый Ч Ч указывает алгоритм шифрования данных. В данном случае применялся симметричный алго ритм TripleDES, в котором для кодирования и раскодирования данных использовался один ключ. Следующий вложенный элемент Ч заимствован из XML Signature. В данном случае предполагается, что уча стникам обмена уже известны все ключи, которые можно применять для шифрования и расшифровки сообщений, поэтому получателю нужно лишь сообщить, какой именно ключ использовался в данном случае. Клю чам можно присваивать любые имена, например LDAP-имена. В примере указано имя ключа Какое бы имя ни использовалось, 8- важно, чтобы для обеих сторон оно четко определяло конкретный ключ.

Последний элемент Ч Ч содержит зашифро ванных которые размещаются во вложенном элементе Value>.

Рис. 3. с зашифрованным телом

/> Ключ можно передать в одном сообщении с зашифрованными данными.

Типичный пример Ч ситуация, когда данные шифруются по симметрично му алгоритму, такому как в примере на рис. 3, а сам ключ открытым ключом получателя сообщения и отправляется вместе с данны ми. Получатель сообщения расшифровывает по своему закрытому ключу симметричный ключ, а затем само сообщение. Для передачи зашифро ванного ключа в XML Encryption предусмотрен элемент EncryptedKey.

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

4. с ключом см, след. стр.

технологии Рис. 4. с ключом

:

...

В отличие от нереалистично простого примера на рис. 3 сообщение на рис. 4 содержит заголовок с элементом Security. Он включает лишь один вложенный элемент Encrypted Key, описанный в стандарте XML Encryp tion. Формат этого элемента во многом совпадает с форматом Data, и в данном примере содержит три уже знакомых нам вложенных элемента: и CipherData. Но в дан ном случае речь идет о зашифрованном ключе, поэтому EncryptionMethod описывает способ шифрования ключа, а не самой информации. Симмет ричный ключ зашифрован открытым ключом получателя по алгоритму RSA. Элемент Keylnfo определяет имя ключа, передаваемого с этим сооб в элементе Поскольку мы считаем, что в предыду примере применялся тот же ключ, то и имя у него такое же. В отли чие от элемента Encrypted Data вложенный в EncryptedKey элемент Cip содержит не информацию сообщения, а зашифрованный симмет ричный ключ.

Кроме того, элемент EncryptedKey включает новый вложенный элемент, не используемый в Data, ReferenceList, который играет важ ную роль в сопоставлении ключа с его помощью данным.

Он содержит URI, обозначающий часть сообщения, зашифрованную клю чом, содержащимся в EncryptedKey. В примере на рис. 4 этим ключом за шифровано все тело сообщения, поэтому здесь указано прозаическое имя Само тело SOAP-сообщения во многом похоже на пример на рис. 3. Отли чие в том, что открывающий тэг элемента EncryptedData содержит атри бут Id с именем Как сказано выше, таким образом дан ные сопоставляются с ключом, которым они зашифрованы. Кроме того, поскольку ключ, которым зашифровано данное сообщение, четко опреде лен, необходимость размещать в элементе EncryptedData вложенный эле мент отпадает.

Согласно есть несколько способов использования XML Enc ryption в SOAP-сообщениях. Можно зашифровать все тело тело и фрагменты заголовка, фрагменты тела и даже вложения (attachments) в сообщение. Разные получатели SOAP-сообщения могут добавлять свои зашифрованные заголовки или расшифровывать адресо ванные им части сообщения. Конфиденциальность в Web-сервисах имеет множество аспектов, соответствующие стандарты должны быть весьма многогранны.

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

Правила безопасности: icy Если есть механизмы обеспечения безопасности, должны быть и соответ ствующие правила. Они проясняют требования безопасности в конкрет ных ситуациях. Например, для Web-сервисов, использующих WS-Security, следует уточнить многие аспекты. Проводит ли этот сервис аутентифика цию при помощи билетов сертификатов и цифровых под писей или использует другие методы? Какие алгоритмы применяются для Новые технологии Web-сервисов цифровых подписей? Какие алгоритмы шифрования обеспечивают кон фиденциальность? Чтобы ответить на эти вопросы следует определить правила безопасности.

Конечно, правила нужны не только для обеспечения безопасности, поэто му Microsoft, IBM и другие компании разработали спецификацию WS Policy. Этот документ определяет общий подход к определению любых правил для Web-сервисов. На его основе создана спецификация WS SecurityPolicy, описывающая XML-элементы для указания правил безо пасности. Эти элементы принадлежат к утверждениям (assertions), так как позволяют Web-сервису однозначно определить соответствующие прави ла. В описаны такие элементы:

Х Token Ч позволяет Web-сервису указать тип принимаемых им маркеров защиты и при необходимости список доверяемых владельцев этих маркеров;

Х Integrity Ч позволяет указывать параметры принимаемых цифровых подписей, например алгоритм хэширования;

Х Confidentiality Ч указывает параметры шифрования, например пользуемый алгоритм;

Х Visibility Ч позволяет указать те части сообщения, которые не долж ны быть зашифрованы.

не регламентирует способы распространения правил безопасности от их создателя всем заинтересованным клиентам. XML-эле менты, выражающие правила, могут пересылаться в SOAP-сообщении или иным способом. Однако WS-Policy определяет общий элемент Policy, ко торый может содержать одно или несколько утверждений правил безо пасности. Вот простой пример Token для Web-сервиса, использу ющего при аутентификации билеты Kerberos:

Этот элемент Policy указывает пространства имен, определенные в WS Policy и WS-Security, и содержит всего один вложенный элемент Security Token. Атрибут usage этого элемента содержит значение Required. Это зна чит, что Web-сервис требует строгого следования данному правилу. Ина че говоря, согласно TokenType данный конкретный Web-сервис для аутен тификации будет принимать только билеты Kerberos.

Элемент Policy может содержать правила, касающиеся маркеров защиты, целостности и других параметров безопасности. Есть и другие возможно сти, включая способы определения Так, Web-сервис может использовать аутентификацию клиентов как через билеты так и при помощи сертификатов указывая, однако, что предпочтительной является аутентификация Kerberos. В лю бом случае значимость этих правил очевидна. Декларируя требования бе зопасности они объясняют, что делать клиенту, чтобы полу чить доступ к этому сервису.

Получение маркеров защиты:

Маркеры защиты Ч основа WS-Security, однако они как бы появляются из ниоткуда, так как механизмы их создания не определены. Дело в том, что наряду с разными видами маркеров защиты существуют различные служ бы для их обработки. Так, чтобы получить билет Kerberos, следует связать ся с Kerberos Key Distribution Center (KDC), а чтобы получить сертифи кат Х.509 Ч с СА. Определяя способы внедрения билетов Kerberos и сер тификатов Х.509 в стандартный XML, WS-Security не описывает способы применения SOAP для связи с KDC, CA или другой службой обработки маркеров защиты.

Эту проблему решает WS-Trust. Цель этой спецификации Ч определить механизм запроса маркеров защиты от соответствующих служб, таких как KDC или СА (рис. 5). Допустим, клиент хочет обратиться к Web-сервису А и Web-сервису В. Допустим также, что для аутентификации Web-сер вису А требуется билет Kerberos, a Web-сервису В Ч цифровая подпись и соответствующий сертификат Х.509. Как видно из схемы, клиенту снача ла следует направить SOAP-запрос к службе маркеров защиты X (т. е. к и запросить билет Kerberos, включенный в элемент Token. Затем клиент может обращаться к Web-сервису А, передав ему по лученный билет в через элемент Security. Далее клиент обращается к службе маркеров защиты Y (СА), запрашивая сертификат Х.509. Получив его, клиент обращается к Web-сервису В, передав получен ный сертификат и соответствующую цифровую подпись.

WS-Trust определяет порядок к службам маркеров защиты и от правку ответов на эти запросы. Взаимодействие строится на двух элемен тах: Request Token и Главный прин цип заключается в отправке содержащего в своем теле элемент и получении SOAP-сообщения, включаю щего элемент с новым маркером защиты.

Пример такого запроса на рис. 6.

технологии защиты Web-сервисов Запрос маркера защиты К (билета Служба маркеров X 2. Возврат маркера К Web-сервис А 3. Обращение к А с К 4. Запрос маркера защиты С Служба Y 5. Маркер защиты С Web-сервис В 6. Обращение к В с маркером защиты С и цифровой подписью Рис. 5.

Рис. 6. Запрос маркера защиты rd> fiequestSectjrityToken> В элемент Security заголовка вложен элемент для аутенти фикации данного запроса. Такой простой способ годится при отправке зап роса через соединение но пересылка через открытые ка налы связи потребует более сложного подхода, вероятно, включающего цифровую подпись и временную метку. Тело сообщения содержит элемент запрашивающий сертификат Если запрос будет удачным, тело ответного сообщения службы маркеров зашиты будет выглядеть примерно так:

rityToken> Возвращаемый сертификат в элементе BinarySecurityToken, описанном в WS-Security. Хотя этого нет в данном примере, вместе с сер тификатом может быть получен закрытый ключ, соответствующий откры тому ключу для данного Для этого в определен элемент в котором может содержаться подобная информация для всех типов маркеров защиты.

Кроме того, WS-Trust вводит дополнений к элементу Request Среди них возможность указать алгоритм и размер ключа, которые должны применяться при создании маркера защиты. Так, иници атор запроса может потребовать использования алгоритма RSA и 1024 битного ключа. и механизм запроса маркера защиты от име ни другого пользователя. Третье дополнение служит для указания срока действия маркера защиты и возможности его продления.

WS-Trust предусматривает также механизм подтверждающего запроса вызов-ответ mechanism), Ч который применим при запросе маркера защиты. Механизма непосредственной аутентификации, показанного на рис. 5, может быть достаточно, но может быть и так, что службе маркеров защиты понадобится дополнительное подтверждение личности инициатора запроса. Что если, как и в предыдущем примере, зап рос не содержит временной метки? Откуда служба маркеров защиты узна ет, что это не воспроизведение того же запроса, но на этот раз отправлен ного хакером? Для предотвращения таких атак перед отправкой запраши ваемого маркера служба маркеров зашиты может потребовать от инициа тора запроса создать электронную для определенного набора дан ных и подтвердить ее.

Новые технологии защиты Web-сервисов Создание контекста:

Иногда для решения проблемы достаточно обменяться парой сообщений.

Например, этого будет достаточно для инициации одной удаленной опе рации. Но допустим, что приложениям нужно обменяться большим чис лом SOAP-сообщений, скажем, для проведения серии операций. В таких случаях полезно создать нечто вроде общего защиты (shared security context) для двух приложений. Типичным способом применения такого контекста может быть определение срока действия шифровально го ключа, используемого при данном обмене. Например, две стороны хо тят создать симметричный ключ и использовать его в течение срока жиз ни определенного контекста. (Примером, не относящимся к Web-сервисам, может служить SSL, где для шифрования каждого нового сеанса создает ся собственный ключ.) определяет XML-типы и взаимодействия (inter actions), позволяющие создавать контексты защиты и соответствующие им ключи Ч т. е. ключи, используемые только в течение данного сеанса. Ос новой этих механизмов служит элемент SecurityContextToken. Согласно данной спецификации каждый контекст защиты имеет имя и общий сек рет (shared так что элемент SecurityContextToken может содержать вложенный элемент Identifier, определяющий уникальное имя для контек и один или несколько зашифрованных ключей для применения в дан ном контексте.

предусматривает три подхода к созданию элемен та SecurityContextToken. Во-первых, его можно запросить у одной из служб маркеров защиты. Для этого, как и в случае запроса маркера защи ты, инициатор запроса отправляет службе с элементом Request Token в теле сообщения. Служба в ответ направляет SOAP сообщение, в теле которого содержится элемент RequestSecurityTokenRes ponse с вложенными элементами SecurityContextToken и RequestedProof последний из которых содержит общий секрет для данного контек скажем, зашифрованный симметричный ключ.

Во-вторых, SecurityContextToken может быть создан одной из сторон и направлен второму участнику обмена. При этом создатель SecurityCon textToken направляет новый маркер в SOAP-сообщении, содержащем эле мент (Для этого не нужно сначала направ лять сообщение с элементом Request Token.) Такое сообщение пол ностью соответствует сообщению службы маркеров защиты из предыду щего оно тоже содержит элементы SecurityContextToken и Requ может быть создан по результатам пере говоров между сторонами, которые будут использовать данный контекст.

Одна сторона направляет второй сообщение с элементом RequestSecurity Token и получает ответ с Response. Вероятно, хотя и необязательно, что в таком обмене будет применяться механизм определенный в В случае успеха переговоров обе сторо ны получают Token и Независимо от способа создания контекст защиты всегда содержит общий секрет, например симметричный ключ. Этот ключ может использоваться для прямого шифрования или подписи сообщений, но sation не рекомендует так делать. Безопаснее будет создать на основе об щего секрета контекста защиты один или несколько производных ключей (derived keys). В спецификации описан алгоритм создания производных основанный на стандарте TLS, Однако стандарт не требует обяза тельного применения данного алгоритма, поэтому производные ключи могут создаваться любым способом.

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

Как показывает нынешняя практика применения SSL и контек сты защиты в сочетании с другими технологиями защиты могут быть очень полезны. позволяет использовать их и в Использование SAML и других XML-маркеров Как я уже говорил, WS-Security описывает два XML-элемента для пред ставления маркеров защиты. Но как быть с другими типами маркеров?

Точнее, как быть с маркерами защиты, уже определенными через В спецификации WS-Security ничего не говорится о представлении таких маркеров, но эту проблему решает спецификация Web Services Security Profile XML-based Tokens. Она определяет общий подход к примене нию маркеров защиты на основе XML совместно с WS-Security и регла ментирует использование двух существующих типов XML-маркеров.

Первый из рассмотренных в спецификации типов маркеров защиты XML определяется при помощи SAML (Security Assertion Markup Language).

Новые Web-сервисов Популярность SAML вполне оправданна, но понять его непросто. (Копия спецификаций по SAML Ч отличное лекарство от бессонницы.) Этот язык позволяет создавать широкий спектр утверждений (assertions) о разных субъектах, таких как люди или приложения. Эти утверждения могут ка саться аутентификации (способа ее выполнения), авторизации (предос тавления доступа к определенным ресурсам) или других аспектов. Сами утверждения можно (но не обязательно) аутентифицировать при помощи XML Signature.

можно включать прямо в элемент Security, не требуя применения новых элементов. В отличие от билетов или серти фикатов SAML-утверждения напрямую встраиваются в На рис. 7 показан несколько упрощенный пример. Как видите, элемент SAML Assertion можно без изменений встраивать в элемент Security. В примере не показан атрибут при помощи которого SAML-маркеру за щиты можно сопоставить цифровую подпись или другую конструкцию SOAP-сообщения.

Рис. 7.

.

Второй тип маркеров защиты XML, оговоренный в Web Services Security Profile for XML-based Tokens, Ч XrML Ч служит для указания прав на цифровую информацию или например, права доступа к опреде ленному Web-сервису или права прослушивания определенного аудио файла. Он содержит элемент license, который можно встраивать в элемент Security так же, как и и Ч сравнительно новые технологии, сейчас их не часто используют в SOAP. Но со временем одна из них или обе могут стать очень популярными. Могут появиться и другие виды маркеров защиты XML. Поэтому требуется регламентирующий использование та ких маркеров в Заключение Web-сервисам нужна защита. Учитывая, что все необходи мые механизмы уже есть лишь определить порядок их использо вания в XML и SOAP), можно решить, что WS-Security и сопутствующие спецификации могли бы быть попроще (а эта статья покороче). Однако многообразие механизмов защиты и необходимость предусмотреть воз можные изменения в будущем требует нетривиальных решений. С появ лением таких решений мечта о безопасных и взаимосвязанных Web-сер висах может стать реальностью. Не знаю, как вы, а я жду этого дня с не терпением.

Чеппел (David Chappell) Ч глава компании Chappell & Associates из Сан-Франциско, штат Калифорния. Проводил семинары по технологиям Microsoft более чем в 30 странах. Его последняя книга Understanding выпущена в прошлом году издательством Яссер Шохуд Проектирование Способность Web-сервисов к взаимодействию и формат XML-сообщений* Web-сервисы предназначены для обмена информацией в виде ний. Если бы вы разрабатывали схему базы вероятно, не захоте ли бы, чтобы эта схема была автоматически создана за вас. Для большей эффективности вы бы ее самостоятельно. Автор утверждает, что это же справедливо и при проектировании Web-сервиса. Вы должны какие данные будут возвращаться Web-сервисом в ответ на запрос, и исходя из их структуры продумать наиболее эффективный формат сообще ний. В этой статье поясняется, как принять соответствующее решение и как создать на основе структуры сообщения.

Создавая Web-сервисы, разработчики зачастую пропускают первый и очень важный шаг: проектирование. Они начинают с добавления Web-сер виса к проекту, а затем добавляют к сервису Web-методы. Хотя такой под ход удобен, это не самый лучший способ создания Web-сервисов, так как при этом не учитывается формат сообщений. Я объясню, почему такой вроде бы удобный подход неадекватен, и покажу более эффективный спо соб создания Web-сервисов в Visual Studio управление данными на себя Как вы строите схему базы данных, создавая приложение, которое работа ет с данными? Начинаете с разработки а затем формируете схе му базы данных с помощью каких-то инструментов? Или же все делаете Публиковалось в MSDN Magazine/Русская 2002. № 6 (декабрь). Ч Прим. изд.

238 Web-сервисы самостоятельно, не забывая о нормализации, ссылочной целостности и оптимизации производительности? Наверное, второе. Даже если вместо языка DDL (Data Definition Language) вы пользуетесь дизайнером схем, то все равно сами контролируете схему базы данных.

Вся суть Web-сервисов в том, чтобы давать нужные данные в нужное вре мя. Когда клиент вызывает Web-сервис, по сети посылается сообщение с XML-данными, и потом клиенту возвращается ответ. Разработка Web-сер виса или его клиента прямо связана со структурой В конечном счете именно от них и зависит приложение. Так почему же вы начинаете создание Web-сервисов с классов и методов, а структуру сообщений остав ляете на усмотрение средств разработки? Вы должны сами спроектировать схему данных (сообщения) и реализовать Web-сервис, поддерживающий этот формат, Ч так же, как и при разработке схемы базы данных.

а не методы Чтобы в терминах а не методов, вам придется изменить образ мышления. Возьмем простой Web-сервис, который прини мает и возвращает информацию о погодных условиях в соответствующей местности. Придя из мира объектно-ориентированно го программирования (ООП), вы испытываете соблазн создать метод принимающий строковый аргумент и возвращающий экзем пляр (рис. 1), Рис. 1. Пример Web-метода // сведения о текущей погоде и вернуть их // в градусах Фаренгейту Открытые string string Humidity;

public Single // Температура как public float см. след. стр.

ZIP Ч Zone Improvement (план почтовых зон в США). Ч Прим.

Способность Web-сервисов к и формат XML-сообщений Рис. 1. Пример Web-метода I get { } * { - 32) * 5/9;

Этот путь ошибочен, так как вы проектируете методы и типы, имеющие смысл лишь в самом Web-сервисе. И клиент Web-сервиса не обязан что либо знать о вашем классе На самом деле клиенту извес тно только то, что он получает составной тип XML-схемы (XSD) Current Weather. XSD-определение типа автоматически создается при запросе Web-сервиса (например, Преобразование XSD-типа в какую-либо структуру данных, имеющую смысл на клиентской стороне, Ч прерогатива клиентского ПО. Например, SOAP Toolkit представил бы экземпляры CurrentWeather в виде списка XML-узлов, интерфейса IXMLDOMNodeList. Инфраструктура Fra mework особенно удобна для преобразования XSD-типов в и иногда это приводит к большим неприятностям. Так,.NET-клиент, добав ляющий Web-ссылку к погодному сервису, приведенному на рис. 1, полу чит класс CurrentWeather Ч результат трансляции одноименного XSD типа:

>

public string public Humidity;

public Single Barometer;

public float 240 Web-сервисы Тот, кто не понимает, в чем суть Web-сервисов, сразу же спросит: Что случилось со свойством и почему FahrenheitTempera Ч поле, а не свойство? А дело в том, что Framework XML сериализует в XML только открытые и доступные для чтения/запи си члены класса сервиса. Поскольку Ч свойство только для оно не и вообще не попадает в класс получаемый клиентом. Более того, автоматически генерируемый клиентский класс всегда содержит открытые поля, а не про цедуры-свойства. Опять же, клиенту известен только XSD-тип Current Weather. А в XSD-типе разницы между процедурами-свойствами и поля ми нет;

для клиента все это данные.

Возможно, теперь вы считаете, что у Web-сервисов серьезные ограниче ния, так как клиент на самом деле не в состоянии получить экземпляр того объекта, который вернул Web-сервис. Но по сути, это не ограничение Web сервиса, а пример почему нельзя считать Web-сервисы одним из ме ханизмов обращения к удаленным объектам (наподобие DCOM).

Проектирование погодного сервиса лучше всего начать с определения со общений. Например, определите сообщение содержащее и сообщение CurrentWeather, включающее сведения о текущей погоде. Образцы сообщений запроса и ответа приведены на рис. 2. Это отправная точка в проектировании Web-сервиса.

Рис. 2, Сообщения запроса и Это запроса, Так как разработчики Web-сервиса и клиента вооружены знанием что ваш Web-сервис принимает сообщение WeatherRequest и возвращает Cur rentWeather, им не придется разбираться в деталях его реализации (напри мер в том, какие члены класса доступны только для чтения и т. д.).

Способность к и формат Формализация структуры сообщения Теперь, когда вы создали образцы сообщений запроса и ответа, подготовьте их формальное описание, чтобы средства разработки вроде Visual Studio могли его считывать и предоставлять вам соответствующие сервисы, например генерировать клиентский прокси.

Чтобы формализовать структуру сообщения, создайте XML-схему, описы вающую запроса и ответа. Хотя это можно сделать в любом текстовом редакторе или редакторе схем, я предпочитаю дизайнер XML схем Studio.

Для работы с дизайнером схем, запустите Visual Studio и выберите New File XML Schema. В этом дизайнере есть специализированный инстру ментарий (toolbox), позволяющий вставлять такие конструкции схем, как объявления элементов и определения типов. Если вы хотите объявить эле мент, WeatherRequest, просто перетащите значок Element из окна инструментария в рабочее окно дизайнера. Для каждого элемента нужно указать два главных атрибута: имя и тип данных. Последний вы либо вы бираете из списка встроенных либо определяете сами. Напри мер, WeatherRequest по умолчанию присваивается встроенный тип string (он содержит строку), a Weather Ч новый пользовательский (cus tom) тип, так как этот элемент включает другие элементы.

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

Потом вы объявляете переменные этого класса, например переменную cw, как на рис. 1.

Дизайнер схем облегчает определение нового типа сводя этот процесс к простому заполнению строк в поле для элемента Current Weather. На рис. 3 показан элемент Weather анонимного (неимено ванного) типа, содержащий элементы Conditions, Humidity, Baro meter, Temperature и CelsiusTemperature.

Прежде чем закончить со структурой сообщения, осталось сделать еще одно: настроить свойство targetNamespace XML-схемы на пространство имен, уникально идентифицирующее Web-сервис или приложение, как показано в окне свойств на 3. Это хороший, но не обязательный стиль, из-за чего многие разработчики могут пропустить столь важный шаг.

Если вам нужна сама XML-схема, вы можете просто переключиться в ре жим просмотра XML, перейдя на вкладку XML, ярлычок которой нахо дится в самом низу окна (рис. 3). Это приведет к загрузке всей схемы в редактор где при необходимости ее можно модифицировать (рис. 4).

Рис. З. Дизайнер Visual Studio Рис. 4. Схема сообщения t f /> />

/> re" /> />

след, стр.

Способность Web-сервисов к взаимодействию и формат Рис. 4. Схема сообщения Определение интерфейса XML-схема на рис. 4 полностью описывает данные, содержащиеся в сооб щениях запроса и ответа, но у сообщений есть и другие аспекты, которые тоже надо описать в формальном виде, понятном компьютеру. Например, используют ли сообщения удаленные вызовы процедур SOAP или стили документов? Как данные кодируются для передачи по сети? Приме няется ли SOAP Section 5 или прямое кодирование (literal coding)? Что бы предоставить эту информацию, вы обязаны создать WSDL-документ (Web Services Description Language). Сейчас в Visual Studio нет встроен ного однако сторонние фирмы предлагают несколько таких программных продуктов. Более WSDL использует граммати ку XML, а значит, для создания годится любой тексто вый или XML-редактор. Грамматика WSDL может показаться немного запутанной из-за огромного количества функций, которые WSDL пытает ся объять. Однако на практике вам понадобится лишь малая часть этих функций, так что можете начать со стереотипного шаблона, приведенного на рис. 5, и адаптировать его под свои потребности.

Рис. 5. Шаблон 1, и пространство имен то что и схеме.

WSDL 2. и location они вашу target to your /> см. след. стр.

Web-сервисы Рис. 5. Шаблон 3. При имена сообщений.

тогда не изменить 4, (parts) и в схеме.

element in /> in /> 5. При измените типа порта.

6. имя именем При добавьте другие 7. сообщений если вы изменяли их выше.

- Х fflessage="sO: /> 6. Оно интерфейса.

9. значение атрибута типа чтобы совпадало с тапа ранее.

10. операции так, оно с указанный пат" /> /> /> к и формат На рис. 6 приведен шаблонный WSDL-документ, настроенный для описа ния интерфейса Weather. Я изменил информацию о разделах сообщений запроса и ответа так, чтобы они указывали на элементы и определенные в схеме ServiceMessages. Кроме того, я на звал операцию GetWeather, а привязку (binding) Ч Weather Interface. В вашем коде эти имена будут присвоены Web-методу и привязке, поэтому их надо тщательно продумать.

Рис. 6. интерфейса Weather f> о /> /> ;

/ /> На этом фаза проектирования завершается. Теперь у вас есть формальное определение интерфейса Web-сервиса, в том числе определение данных в каждом сообщении запроса и ответа. С этого момента разработчик серви са может приступать к реализации интерфейса, а разработчик клиента Ч программировать в с интерфейсом. Заметьте: разработчику клиента не обязательно дожидаться реализации сервиса. То есть разработ ку клиента и сервиса можно вести параллельно.

Реализация интерфейса Для реализации интерфейса Web-сервиса воспользуйтесь утилитой из Microsoft Framework SDK. Она работает с и генерирует класс-заглушку (stub>

Например, чтобы класс, реализующий интерфейс сервиса Weather, запустите wsdl.exe с ключом /server, передав URL-адрес WSDL документа:

С:\> wsdl.exe /server ace. wsdl (R) Web Language Utility [Microsoft (R) Framework, 1.0.3705.0] Copyright (C) Microsoft All rights reserved.

Writing file По умолчанию wsdl.exe код на С#, но ключ /language позволя ет перейти на Visual Basic или JavaScript. В нашем примере создан ный файл WeatherStub.cs содержит абстрактный класс интерфейс Weather. Класс включает метод ко торый принимает строку и экземпляр Weather. A rentWeather Ч это еще один класс, созданный в соответствии с типом Cur rentWeather, определенным в XML-схеме.

Написание кода сервиса начинается с добавления этого интерфейсного класса к проекту, созданию нового Web-сервиса и изменения последнего таким образом, чтобы он наследовал от абстрактного класса Weatherlnter face. Далее переопределите метод GetWeather базового класса и помести те туда логику реализации, как показано на рис. 7. Чтобы метод GetWeat her был доступен через SOAP, добавьте атрибут А чтобы этот метод стал истинной реализацией операции определенной ранее в Weather вам надо также добавить XmlElement к воз вращаемому значению и атрибут установив его свойство как Web-сервисов к и Рис. 7. Наследование от класса using namespace {>

public ( // Сюда поместите код, получающий сведения о погоде Если вы ведете разработку на Visual Basic добавлять эти атрибуты вручную не требуется. Visual Studio автоматически добавляет их к коду, когда вы выбираете метод Weather из меню переопределенных методов.

Собрав Web-сервис и перейдя к его автоматически созданному документу, вы обнаружите, что в нем довольно много информации. Это, кстати, настоящая проблема. WSDL-документ содержит, во-первых, пол ную копию Weatherlnterface, а во-вторых, и два других интерфейса, POST и GET.

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

Поэтому первое, что надо сделать, Ч удалить копию интерфейса из документа сервиса и как-то заставить его ссылаться на face.wsdl, созданный ранее. Для этого добавьте атрибут к самому Web-сервису, укажите имя реализуемой а также к в котором эта привязка определена. Кроме того, настройте свойство binding атрибута для каждого Web-метода так, чтобы оно указывало на реализацию конкретной операции, определенной в привязке. На рис. показан Web-сервис с внесенными изменениями.

Рис. 8. Добавление информации о привязке using Services.

using { * public>

i } Pa public // йода о return Наконец, я рекомендую отключить HTTP GET- и POST-привязки в Web-сервиса. Чтобы запретить использование этих протоколов для конкретного просто отредактируйте его файл web.config и добавьте раздел webServices в Способность к и формат XML-сообщений Х А чтобы отключить эти протоколы для всей системы, модифицируйте файл удалив HttpGet и HttpPost из списка протоколов.

Теперь, Web-сервис и перейдя к его вы увидите облегченную версию документа, которая просто импортирует и добавляет определение сервиса (рис. 9). Определение сер виса можно рассматривать как специфическую реализацию интерфейса, определенного в Рис. 9. Конечный com/Weather" Импорт /> /> Программирование с использованием интерфейса Для создания обращающихся к интерфейсу Weather, можно вос пользоваться либо либо командой Add Web Reference в Visual Studio и тем самым сгенерировать прокси-класс на основе интерфейса.

Заметьте;

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

Private Sub _ sender As e As Handles Dim As New = Dim As = Sub Заключение Web-сервисы предназначены для обмена данными в виде XML-сообщений между приложениями, поэтому создание Web-сервиса требует тщательно го проектирования этих сообщений с помощью XML и Если вы начинаете с проектирования сообщений, а не методов, то тип дан ных, которые должен принимать и возвращать ваш становит ся очевидным. Проектируя сообщения с применением XSD и вы создаете формальное определение интерфейса. И тогда клиент Web-серви са можно программировать на основе этого интерфейса параллельно с его реализацией разработчиком Web-сервиса. В следующий когда вы бу дете создавать проект, связанный с Web-сервисом, начните с проектирова ния формата сообщений в дизайнере XML-схем Visual Studio.

Яссер Шохуд (Yasser Shohoud) Ч менеджер программы в группе Microsoft XML Messaging Team. Автор книги Real XML Web Services Wesley, 2002).

Тим Эвалд Web-сервисы Доступ к SOAP-сообщениям, передаваемым при взаимодействии с Web-сервисами ASP.NET* обмениваются XML-сообщениями. В большинстве современных инструментов для Web-сервисов этот факт тщательно скрывается от программистов, и при использовании Web-сервисов вместо обработки сообщений вызываются методы объектов. Но нередко возникает необходи мость в доступе к реальным передаваемым по сети. Как это сделать, вы сейчас и узнаете.

Web-сервисы обмениваются XML-сообщениями. В большинстве совре менных инструментов для создания Web-сервисов этот факт тщательно скрывается от программистов, и при использовании Web-сервисов вместо обработки сообщений вызываются методы объектов. Ну, а если нужно по лучить доступ к настоящим XML-данным, передаваемым по сети? В ASP.NET сервисам не предоставляется доступа к самим SOAP-сообщени ям, но, немного попотев, такой доступ можно получить через встроенные ловушки расширения (extensibility hooks).

Сначала рассмотрим Web-сервисы ASP.NET в общих чертах. При разра ботке Web-сервисов в Visual Studio вас побуждают использовать инфраструктуру ASP.NET определенным образом. В частности, предлага ется реализовать сервис как класс, предоставляющий набор методов с ат рибутом [WebMethod], автоматически генерировать его WSDL-описание Публиковалось в MSDN Magazine/Русская Редакция. 2003. № 3 (март). Ч Прим, изд.

(Web Services Description Language) и а затем разра батывать клиент. Однако инфраструктуру Web-сервисов можно использо вать и по-другому.

В статье Проектирование. Способность Web-сервисов к взаимодействию и формат в декабрьском номере Magazine/Русская за 2002 Яссер Шохуд (Yasser рассказывает о важности явного определения сообщений, отправляемых и принимаемых Web-сервисом. Он доказывает, что начинать разработку Web-сервиса надо с создания описания на языке WSDL, а потом генери ровать в соответствии с описанием и сервис, и клиент. Я, как и многие другие, разделяю эту точку зрения. Подход, при котором вы сначала созда ете позволяет задействовать преимущества модульнос ти инфраструктуры Web-сервисов ASP.NET и использовать только необ ходимые ее части. Значит, если вы начнете с WSDL-описания, то в даль нейшем вам не придется заботиться о его автоматической генерации из кода сервиса. С моей точки зрения, функциональность Web-сервисов ASP.NET делится на четыре основные группы:

Х автоматическая генерация WSDL-описаний с возможностью расши рения;

Х диспетчеризация сообщений;

Х фильтрация сообщений;

Х сериализация и объектов.

В зависимости от своих потребностей вы можете использовать, игнориро вать или изменить любую из этих групп. Шохуд и многие другие считают, что основной принцип разработки сервисов Ч игнорировать автоматичес кую генерацию WSDL. Но главное в том, что инфраструктура Web-серви сов ASP.NET достаточно гибка и у вас есть из чего выбирать. Цель этой и следующих моих статей Ч раскрыть возможности выбора и продемонстри ровать, насколько многого достичь, применяя для Web-сервисов инфраструктуру Microsoft Framework. Здесь я покажу, как получить доступ к SOAP-сообщениям сервиса, что по сути ведет к отказу от сериа лизации и применяемых для автоматического преобразо вания XML в объекты.

Зачем обращаться к SOAP-сообщениям?

Инфраструктура Web-сервисов ASP.NET построена на предположении, что разработчики предпочитают работать с объектами, а не с XML. По умолчанию каждое получаемое Web-сервисом от клиен та, десериализуется в объекты и значения, которые могут быть переданы Доступ к методу в качестве входных параметров. По завершении метода выходные параметры и возвращаемое значение в пе редаваемое обратно клиенту. Цель всего этого Ч скрыть использование А как работать с напрямую? Может, вы, например, хотите выполнять к получаемым сообщениям. Или Web-сервис получает от SQL Server, и вам нужно передать XML-данные клиенту без пре образования в объекты, так как инфраструктура все равно их в XML. А может, у вас имеется слабо сопряженная (loosely coupled) сис тема, поддерживающая пять форматов заказов на товары, и вы собираетесь использовать XSLT для их нормализации во внутренний формат для даль нейшей обработки. Наконец, не исключено, что вы используете объекты вроде или реализации которые инфраструктура Web-сервисов ASP.NET не может автома тически, и вы собираетесь сериализовать их самостоятельно. В любой из этих ситуаций было бы удобнее работать с через ме тоды пространства имен в Framework.

Инфраструктура Web-сервисов ASP.NET обеспечивает ограниченную под держку доступа к XML-данным через некоторые функции DOM (Docu ment Object Model) API, в частности из пространства имен XmlElement. Это, конечно, шаг в верном направлении, но этого недоста точно. Оптимальным был бы любой подход, при котором SOAP-сообще ния с XML-данными, принимаемые и отправляемые Web-сервисом, обра батываются на уровне потоков (streams). Б пространстве имен есть классы для работы с потоками, и XmlWriter, которые ле жат в основе всех высокоуровневых классов, осуществляющих ввод-вывод XML-данных. Если бы SOAP-сообщения были доступны через потоки, тогда XmlReader и XmlWriter могли бы обрабатывать эти сообщения, ис пользуя DOM, XSLT-преобразования и любые другие XML-технологии.

Получение доступа к входным и выходным потокам ASP.NET не предоставляет доступа к потокам, содержащим входящие и исходящие SOAP-сообщения, передаваемые при взаимодействии с Web сервисом. Но такой доступ можно получить через SOAP-расширение (SOAP extension) Ч это фильтр, размещаемый между HTTP-обработчиком запросов, направляемых и классом, действительно реализующим сервис. SOAP-расширения могут обрабаты вать входящие сообщения перед вызовом метода сервиса, а исходящие Ч после его выполнения. Особых премудростей в этом нет.

Ключевое значение в архитектуре имеет возможность создавать цепочки входных и выходных потоков. Если SOAP-расширений нет, инфраструктура Web-сервисов работает напрямую с потоками, пред Web-сервисы ставляющими HTTP-сообщения. SOAP-расширения могут подменять HTTP-потоки собственными потоками, обычно экземплярами System.IO. Web-сервис в итоге работает с потоками, а копирование данных между замещающими и настоящими потоками возлагается на SOAP-расширения. Слово взято в кавычки, так как любое SOAP-расширение может иметь дело с потоками, замещенными другим SOAP-расширением. Вот почему говорят, что рас образуют цепочки потоков.

Предоставление доступа к входным и выходным потокам Ничто не мешает SOAP-расширению сделать потоки, с которыми оно ра ботает, доступными Web-сервису. Тогда методы сервиса получат возмож ность самостоятельно читать и записывать входящие и исходящие SOAP сообщения. Но тут есть одна тонкость. Если метод записывает свое в подключенный в цепочку поток, предоставляемый SOAP-рас ширением, а инфраструктура Web-сервисов ASP.NET автоматически гене рирует исходящее SOAP-сообщение, записываемое в тот же поток, возникает проблема. Решение Ч предоставить методу два выходных пото ка: используемый методом и используемый инфраструктурой. Базовая архитектура Web-сервиса показана на рис. 1.

Входной Рис. 1. Схема передачи сообщений в Обычно Web-сервисы ASP.NET напрямую работают с входными и выход ными HTTP-потоками. Но мы рассмотрим пример другого подхода. Класс SOAP-расширения XmlStreamSoapExtension подключает выходной HTTP поток к цепочке и предоставляет уровню сериализации поток в памяти (т. е. этот уровень работает не с выходным HTTP-потоком, а с потоком в Доступ к памяти, взаимодействующим с выходным HTTP-потоком). Кроме того, этот класс создает дополнительный выходной поток, в который метод Web-сервиса записывает свои исходящие SOAP-сообщения. Заметьте: для входного потока не создается. Вместо этого просто предоставля ется прямой доступ к соответствующему HTTP-потоку. Метод сервиса обращается к входным и выходным потокам через статические свойства класса Реализация в виде прототипов Реализация класса показана на рис. 2 (для упро щения я опустил ряд несущественных деталей). Метод дает возможность SOAP-расширению замешать потоки с входящими и исходя щими сообщениями. Так как наше расширение замещает только выходной поток, а входной оставляет как есть, используется флаг output, чтобы оп ределять, какой поток надо замещать. При работе с объектом SOAP-pac ширения сначала всегда запрашивается подключение в цепочку входного потока и только потом Ч выходного. Флаг output в реализации класса первоначально имеет значение false, чтобы пустить запрос на подключение в цепочку входного потока. Это сделано для большей эффективности (чтобы не создавать лишнюю копию входя щего сообщения).

Рис. 2. Реализация // Класс // доступ к public>

указывающий ввод или output = false;

// // Stream // выходной поток ftSP.

Stream // // // исходный поток result // Замещаем в памяти поток result * new см. след. стр.

Рис. 2. Реализация { true;

} return result;

обработки // во параметры // выходных параметров в case :

// в // и в текущем Current.

Current.

// поток в памяти, куда и ссылку в * break;

:

// потока в памяти, // переходим в его начало и в * в поток назначения см. след. стр.

Доступ к Рис. 2. Реализация writer writer.

Основная работа выполняется в методе ProcessMessage вызывается до и после десериализации входящего сообщения во входные параметры, а также до и после выходных параметров в ис ходящее сообщение. После десериализации входящего сообщения SOAP расширение возвращается в начало входного HTTP-потока, благодаря чему метод может читать поток (при десериализации курсор потока пере мещается вперед), и создает новый поток в памяти для записи исходящих сообщений метода. Этот выходной поток, является вто рым выходным потоком, необходимым для реализации нашей схемы.

(Первый выходной поток, chainedOutputStream, создается при втором вызове Ссылки на оба потока сохраняются в наборе (collec tions) Items текущего под ключами и соответственно. После сериализации исходящего со общения ProcessMessage копирует содержимое второго выходного потока, в выходной HTTP-поток Ч (Боль шинство SOAP-расширений в этот момент копирует содержимое своих подключенных в цепочку выходных потоков в выходной HTTP-поток.) Метод просто копирует данные из одного потока в другой.

Для упрощения работы с Extension служат два вспомога тельных класса: (помечает метод как использующий данное SOAP-расширение) и (обеспечивает доступ к входным и выходным потокам, содержащим исходные SOAP-co как к статическим свойствам). Реализация SoapStreams показа на рис. 3.

Рис. 3. Реализация класса SoapStreams public SoapStreams public static см. стр.

9- Рис. 3. Реализация return public get return (stream) Связываем все воедино Я создал простой Web-сервис, суммирующий числа. На этом примере мы и посмотрим, как работает Форматы сообще ний сервиса (рис. 4) определены на основе XML Schema. Эти сообщения используются при реализации единственной операции Add, описываемой WSDL-кодом (рис. 5).

Рис. 4. Форматы сообщений Web-сервиса p:

Доступ к операции Add о Import Add" /> :

/> output > /> На рис. 6 показан пример сгенерированного по этому WSDL утилитой с указанием в командной строке ключа /ser ver и затем измененного нами. Атрибут [XmlStreamSoapExtension] щает инфраструктуре что класс обра батывает сообщения, используемые при взаимодействии с методом Add.

Обратите также внимание на описания параметров;

поскольку метод работает с напрямую, или десериализация параметров не нужна. Один из побочных эффектов этого изменения Ч невозможность автоматически сгенерировать правиль ное WSDL-описание класса. Если вы (как и я) предпочитаете сначала со здавать WSDL-описание, это не проблема. В качестве альтернативы мож но было бы реализовать отражатель (SOAP extension reflector), модифицирующий WSDL-описание так, чтобы оно отражало форматы XML-данных, принимаемых и передаваемых мето дом. [Детали см. в статье Скотта (Scott Short) XML-схемы. Ис пользование внешних XML-схем в ASP.NET через инфраструктуру импор в Magazine/Русская за декабрь 2002 г.;

ее оригинал доступен по ссылке Рис. 6. Web-сервис, по :.

{ E ] t Literal, /* */ void // с т допустимость // (validating reader) в схему valid = new // Загружаем и проверяем на допустимость сообщение doc // и XSLT след. стр.

Доступ к Рис. 6. Web-сервис, сгенерированный по WSDL-описанию // Обрабатываем и исходящее null, new В методе Add входящее сообщение просто считывается из потока с помо щью и представляется в виде DOM. При этом сообщение проверяется на соответствие схеме сервиса (инфраструктура Web-сервисов ASP.NET по умолчанию этого не делает). Затем применяет ся при котором генерируется исходящее сообще записываемое в Это преобразование, выглядит так:

* select= А как насчет исключений?

Осталось одно: как быть с исключениями? Обычно инфраструктура Web сервисов ASP.NET сопоставляет исключениям элементы SOAP Fault. Но в нашей реализации игнорирует ся поток который содержит исходящее генерируемое инфраструктурой, и используется выходной поток appOutputStream, создаваемый методом. Проблема...

Из этой ситуации два выхода. Первый Ч требовать, чтобы каждый метод, использующий сам обрабатывал исключения и при необходимости генерировал исходящее содержащее элемент SOAP Fault. Второй Ч добавить в метод ProcessMessage SOAP логику поиска элемента SOAP Fault в исходящем сообщении, генерируемом инфраструктурой. Если элемент Fault присутствует в сооб значит, возникло исключение и нужно вернуть сообщение, содер жащее Fault. Доработанная версия ge, в которой реализован второй способ, показана на рис. 7.

Рис. 7. Поиск элемента SOAP // обработки // после входящих во входные параметры // и сериализации в исходящие сообщения public override void :

// в начало // и сохраняем // Создаем поток в куда метод // и break;

case ;

// Сканируем цепочку поток // и SOAP Position 0;

reader = reader.

"Header") if // найден. Переходим в // в выходного потока и копируем // в HTTP-поток 0;

else ;

// не содержимое потока см. след. стр.

Доступ к Рис. 7. Поиск элемента SOAP Fault f{ в для исходящих // переходим в его начало и копируем // в таток.

8;

Зачем использовать XML?

Благодаря расширяемости инфраструктуры Web-сервисов ASP.NET мож но, написав довольно простое предоставить методам сервиса доступ к исходным SOAP-сообщениям, Зачем? SOAP и Web-сер висы являются XML-технологиями. Зачастую удобно реализовать Web сервисы с помощью объектов, скрывающих нижележащие XML-средства, но при этом нельзя использовать такие мощные инструменты, как XPath, XSLT и XML Query. Пожалуй, при сложении двух чисел можно обойтись без работы на уровне (хотя проверка на соответствие XML-схеме очень полезна), но суть не в этом. Главное, что работать с XML во многих случаях проще, чем с объектами, да и возможность обрабатывать SOAP сообщения напрямую тоже не помешает. Вы можете спросить, почему я не пошел до конца и не реализовал Web-сервис как низкоуровневый HTTP обработчик (такой подход я и применял раньше). Основное преимущество работы (по большей части) в рамках инфраструктуры Web-сервисов ASP.NET заключается в том, что при необходимости вы сможете использовать и объектное представление данных, что немыслимо в элементарном HTTP решении.

Исходный код для этой статьи можно скачать по ссылке rosoft.com/msdnmag/code03.aspx в разделе за март.

Тим Эвалд Ч руководитель программы по Web-сервисам XML в Microsoft. Работает над спецификациями и сов, а также доводит эту информацию до Автор книги Building Scalable Applications 2001).

С ним можно связаться по адресу tewald@microsoft.com.

Тим Обязательные заголовки в Web-сервисах Инфраструктура Web-сервисов A5P.NET позволяет программировать с использованием заголовков Автор рассматривает специфическую проблему, возникающую при работе с обязательными SOAP-заголовками, и три способа ее решения.

Инфраструктура Web-сервисов ASP.NET позволяет программировать с использованием заголовков SOAP-сообщений. К сожалению, у модели обработки обязательных заголовков (mandatory headers) есть недостаток, который выражается в необходимости написания дополнительного кода, запрещающего запуск Web-сервиса без обработки обязательного заголов ка. Сегодня мы рассмотрим специфическую проблему, возникающую при работе с обязательными SOAP-заголовками, и три способа ее решения.

Обязательные заголовки SOAP-сообщения могут включать необязательный элемент Header из про странства имен SOAP, который, как сказано в версии 1.1 спецификации SOAP, предоставляет гибкий механизм для расширения сообщений де централизованным модульным способом без предварительного согласова ния между сторонами коммуникационного При наличии элемен та Header в него может быть включено несколько элементов расширения (extension elements) (однако их число может быть равно 0). Элемент рас ширения может содержать необязательный атрибут кото рый также входит в пространство имен SOAP и указывает на то, что обра ботка данного элемента На рис. 1 показан пример сообщения Публиковалось в 2003. № 5 (май). Ч Прим.

Обязательные заголовки в Web-сервисах с обязательным заголовком. По существующему соглашению, если полу чатель не в состоянии обработать обязательный заголовок, он не должен обрабатывать соответствующее сообщение. Такой подход довольно рас плывчато оговорен в пункте 4.2.3 спецификации SOAP 1.1:

Если элемент Header помечен must Understand со значением л1, получатель сообщения либо [обязательно] следует семантике (согласно полному имени элемента) и осуществляет корректную обработку, либо отка зывается от обработки сообщения.

Рис. 1. Пример обязательного заголовка что этот обязательный -->.

В Candidate Recommendation спецификации SOAP 1.2 (часть 1, раздел 2.4) устранены недомолвки и четко определена семантика обработки обяза тельных заголовков:

что обязательные блоки влияют на семантику остальных блоков или Body. Поэтому узел [обязательно] обрабатывает каждый адресованный ему обязательный блок или отказывается от обработки всего генерируя ошибку (см. разде лы 2.6 SOAP Messages и 5.4 SOAP Внутренняя инфраструктура Web-сервисов ASP.NET предоставляет мо дель для операций над заголовками Увы, она допуска ет обработку сообщения, даже если в нем содержится обязательный заго ловок, который не поддерживается или не распознается целевым методом.

И хотя ошибка все же генерируется, но лишь после того, как будет выпол нен код Web-сервиса.

Обязательные заголовки в ASP.NET Когда диспетчер сообщений (message dispatcher) Web-сервисов ASP.NET разбирает сообщение, он использует содержимое элемента Body в качестве входных параметров для вызова метода. Перед вызовом содержимое эле мента Header (при его наличии) может быть в поля или свойства целевого объекта. В ходе работы метод может просматривать эти поля или свойства, определяя заголовки сообщения. Сопоставление заго ловков полям или свойствам не обязательно и контролируется значением атрибута Soap Attribute (рис. 2).

Рис. 2, Сопоставление полям или свойствам Этот microsoft.

>

public Baz;

public>

// Если заголовок // он будет помещен в это // // Атрибут [SoapHeader] диспетчеру // поле для соответствующего заголовка при // наличии. Диспетчер определяет, какой // public string sb * ran, // при выполнении получает к foo.

в не будет равно if null) } :

Метод Ваг помечен атрибутом [SoapHeader], который ссылается на поле с именем foo. Механизм отражения (reflection) позволяет диспетчеру сооб щений определить, что foo Ч это экземпляр Foo подкласса Диспетчер знает, что все типы, производные от SoapHeader, представляют XML-элементы, которые могут располагать ся в заголовке сообщения. В данном случае атрибут [XmlRoot] сообщает Обязательные заголовки ASP.NET диспетчеру, что класс Foo представляет заголовок Foo из пространства имен Если этот элемент появляется в за головке обрабатываемого сообщения, диспетчер десериализует его в поле foo, делая его доступным при выполнении метода Ваг.

Базовый класс SoapHeader (не путайте с классом содержит булево свойство Десериализуя заголовок в поле или диспетчер проверяет, является ли этот заголовок обя зательным (т. е. проверяет, содержит ли XML-элемент атрибут mustUn значение которого равно 1 или Если заголовок обязатель ный, то диспетчер для соответствующего свойства или поля устанавлива ет свойство в true. По нему метод может определить, обязательна ли обработка этого заголовка. На рис. 3 дан при мер модифицированного метода указывающего, является ли вок Foo обязательным.

Рис. 3, Свойство MustUnderstand г * if is { // Обратите внимание: строка теперь о ли заголовок обязательным is and :

Свойство SoapHeader.MustUnderstand позволяет диспетчеру сообщений Web-сервисов сообщать о том, что данный заголовок является обязатель ным. Но в спецификации SOAP говорится (ясно или расплывчато в за висимости от версии), что если обязательный заголовок не нужно генерировать ошибку. То есть ваш код должен информировать дис петчер о распознаваемых им заголовках. Для этого в классе SoapHeader имеется второе с именем По завершении вызова метода инфраструктура проверяет свойство DidUnderstand каждого обя 268 Web-сервисы зательного поля или из использовавшегося в ходе работы чтобы убедиться, что все обязательные заголовки распоз наны. Если для любого из них значение свойства Must Understand равно true, а свойства false, генерируется ошибка, сообщающая, что обязательный заголовок не был распознан.

На рис. 4 показана третья реализация метода в которой свойство DidUnderstand поля foo является ли заголовок обязательным.

4.

public string 8ar() I sb if null) ?

;

что заголовок // предотвратить ошибки if * return В ожидании неожиданностей На первый взгляд, модель кажется впол не разумной, однако у нее есть существенное ограничение. Основная про блема в том, что иногда клиент может присылать обязательные заголовки, которых вы не ждали. Скажем, мой сервис может считать, что заголовок Foo является необязательным, но и в этом случае работает корректно. Та кое легко проделать с любым ожидаемым заголовком. Если вы сопостав ляете заголовок полю или свойству, не забудьте установить его свойство DidUnderstand в true там, где это нужно. (Или для большей безопасности присваивайте true во всех случаях это ничему не повредит, даже если заголовок не является обязательным.) Обязательные в Но как быть с заголовками, которых ваш сервис не ждет? Что, если кли ент решит объявить обязательным заголовок, о котором ваш сервис никог да не слышал? Если сервис не знает о существовании такого заголовка, он не сумеет сопоставить его определенному полю или свойству, а следова тельно, не узнает, является ли этот заголовок обязательным, и не сообщит, был ли он распознан. В то же время инфраструктура должна требовать корректной обработки обязательных заголовков в соответствии со специ фикацией SOAP. Что происходит в этом случае?

В идеале, когда диспетчер обнаруживает обязательный заголовок, который он не может сопоставить полю или свойству, код не выполняется, а про сто генерируется ошибка. Конечно, такое решение предполагает, что все обязательные заголовки сопоставляются членам вашего класса. И для уни версальной модели обработки заголовков это допущение некритично. К сожалению, на практике все не так. Вы сами должны сопоставить неизве стные заголовки полю или свойству и отследить наличие обязательных заголовков, оставшихся нераспознанными. Именно для этого служит класс Ч это подкласс SoapHeader, используемый диспетче ром сообщений для представления любого заголовка, не сопоставленного никакому полю или свойству. На рис. 5 показана новая версия моего сер виса, обрабатывающая неизвестные заголовки.

Рис. 5.

public :

Foo // для неизвестных // Второй атрибут указывает // заголовки, кроме Foo, неизвестных заголовков [WebMethod] ] string // все // и помечаем как if null * Проверяем все неизвестные заголовки и генерируем // хотя б один из них см. след. стр.

Рис. 5.

Nader in // заголовок if // строку с * header;

// генерируем // с SOAP throw new // После выполняем реальные if Bull) is is and ?

:

Как и в других производных от SoapHeader, атрибут [SoapHeaderj сообщает диспетчеру, что делать с заголовками, которые иначе он не мо жет обработать. Новая версия метода Ваг включает атрибут, сообщающий инфраструктуре, что все неизвестные заголовки следует сопоставлять полю (которое представляет собой массив на тот случай, если неизвестных заголовков окажется несколько). Метод начинается с кода обработки заголовка. Сначала он помечает любой обязательный заго ловок Foo (сопоставленный полю как распознанный. Затем, если кли ент передал неизвестные заголовки (которые сопоставляются полю unk метод проверяет, является ли какой-нибудь из них обяза тельным. Если обнаружен неизвестный обязательный заголовок, генери руется согласно спецификации SOAP.

Обязательные в Готов поспорить, что подавляющее большинство написанных к настояще му времени Web-сервисов ASP.NET не проверяет наличие неизвестных обязательных заголовков в явном виде. Это значит, что, если клиент от правит сообщение с обязательным заголовком, который не будет сопостав лен какому-то полю или свойству, то метод не сможет пометить этот заго ловок как распознанный. В итоге диспетчер сгенерирует ошибку, но лишь после выполнения сервиса! Это прямое нарушение спецификации SOAP, согласно которой при наличии нераспознанных обязательных заголовков сообщение вообще не должно обрабатываться. А на практике ваш сервис выполняется, считая, будто все в порядке, но клиенту возвращается SOAP Короче, если вы хотите, чтобы ваш сервис соответствовал спецификации SOAP, предусматривайте корректную обработку неизвестных обязатель ных заголовков.

Решить проблему раз и навсегда Soap Unknown Header (рис. 5) решает проблему неизвестных обязательных заголовков. Однако включать этот код в каждый метод, работающий как Web-сервис, утомительно. К счастью, есть более простой способ: включи те код в SoapExtension. На рис. 6 показан полный исходный код определяющего наличие неизвестных обязательных заголовков до запуска сервиса.

Рис. 6.

// // обязательных генерирует ошибку, если public>

} аи. след. стр.

Рис. 6.

// в case { { if // Если // помечаем как stand = } if // // = header;

string new break;

} Метод Process Message просматривает все заголовки обрабатываемого со общения. Все известные заголовки он помечает как распознанные (т. е. все заголовки, сопоставленные или свойству любого подкласса Soap Header, кроме SoapUnknownHeader). Если он обнаруживает неизвестный обязательный заголовок, генерируется SOAP-ошибка Must Этот способ работает даже при отсутствии в классе Web-сервиса поля или свойства-массива SoapUnknownHeader. Такое решение предполагает, что все известные заголовки являются распознаваемыми и что все обязатель ные заголовки известны, но же это приемлемое допущение.

Обязательные в Учитывая универсальность данного расширения, имеет смысл настроить его для работы со всем Web-сервисом, а не с единственным методом.

Это можно сделать, добавив в файл (или даже код:

Odd /> Теперь моему сервису можно вернуть первозданный вид (рнс. 7). Заметь те: из кода удален блок обработки неизвестных заголовков. При наличии в нем нет необходимости.

Рис. 7. Пример сервиса, использующего MustUnderstandExtension { sb = if null) is else { // внимание: создаваемая строка теперь // заголовок is and ?

:

А как насчет WSE?

В Web-сервисах ASP.NET разработчики все чаще используют расширения Web Services Enhancements (WSE) для библиотеки классов Microsoft Framework, чтобы ввести поддержку дополнительных протоколов Web 274 Web-сервисы сервисов в свои приложения. предоставляет совершенно другую мо дель обработки заголовков, и, если вы используете эти ре шать проблему неизвестных заголовков следует иначе.

При обработке сообщения пропускает его через серию входных фильтров. Каждый фильтр отбирает один или несколько уда ляет их из SOAP-сообщения и представляет данные этого заголовка как часть объектной модели которую сопоставляет с дан ным сообщением. Хотя такую модель можно совместить с моделью обра ботки заголовков Web-сервисов ASP.NET, легче использовать модель отдельно.

Pages:     | 1 | 2 | 3 | 4 | 5 |    Книги, научные публикации