Продолжается подписка на наши издания! Вы не забыли подписаться?

Создание безопасных Web-сервисов

Автор: Vijay P. Mehta
Опубликовано: 03.07.2006

Web-сервисы и бинарные вложения всегда плохо совмещались, когда дело доходило до реализации безопасности. Но функциональность, появившаяся в Web Services Enhancement 3.0 (WSE3), должна существенно упростить работу с бинарными вложениями и Web-сервисами.

IT-индустрия годами обсуждала формат бинарных вложений для Web-сервисов. За первенство боролись SOAP with Attachments (SwA), Direct Internet Message Encapsulation (DIME) и Message Transmission Optimization Mechanism (MTOM). Первые два, SwA и DIME, содержали фундаментальный дефект – в них не было средств, позволяющих применить к сообщению WS-Security (спецификация стандарта безопасности для Web-сервисов). MTOM, более молодая спецификация, не имеет такого недостатка, и W3C недавно присвоила MTOM статус "Recommended".

Microsoft долго колебалась, но поддержка MTOM в новой версии WSE демонстрирует более четко выраженную позицию. Кроме поддержки MTOM WSE3 содержит несколько новых возможностей, включая готовые решения обеспечения безопасности для Web-сервисов, а также набор расширений модели политик, упрощающих настройку безопасности во время исполнения.

Я покажу, как использовать некоторые новые возможности, на примере, работающем с бинарными вложениями из Web-сервиса с помощью содержащейся в WSE 3.0 MTOM-функциональности. Пример требует наличия на машине Visual Studio 2005 и WSE3 (скачать WSE3 можно по адресу http://www.microsoft.com/downloads/details.aspx?familyid=018a09fd-3a74-43c5-8ec1-8d789091255d&displaylang=en). Когда я писал эту статью, WSE3 существовал только в версии "Community Technical Preview" (CTP), то есть в виде ранней бета-версии. Писать о CTP-версии рискованно, но текущий релиз WSE (2.0 SP3) не поддерживается .NET 2.0, а писать о чем-то, что устареет в ближайшем будущем, никакого желания нет. Примите во внимание то, что описываемые возможности могут измениться, как и в случае любой бета-версии, но основные концепции, описанные ниже, останутся теми же, даже если их реализация и поменяется слегка. Для работы примера потребуется также установленный SQL Server. Я использовал SQL Server 2000, но пример будет работать, как задумано, и с MSDE, и с SQL Server 2005.

Идея примера появилась, когда в проекте, над которым я работал, появилась необходимость в разработке Web-сервиса для обмена PDF-файлами. Точнее, клиенту нужен был способ цифровой подписи и шифрования PDF-файлов отправляемых и получаемых в/из БД с помощью Web-сервиса. Единственным на то время способом сделать это было создание большого количества кода, при этом игнорируя части WS*-спецификаций, касающиеся бинарных вложений. Спецификации бинарных вложений просто не давали разработчику эффективного способа применить WS-Security к сообщениям Web-сервиса.К счастью, со времени работы над этим проектом многое изменилось, WS* теперь поддерживает MTOM, обеспечивающий безопасный обмен бинарными вложениями (технически – MIME-вложениями) с помощью Web-сервисов. Другое ключевое преимущество использования MTOM в том, что этот протокол позволяет пересылать массивы байтов без кодирования в Base64 (как его предшественники), а это означает, что размер сообщения гораздо меньше, чем при использовании DIME или SwA.

Новые возможности WSE3

Прежде чем перейти к собственно примеру, рассмотрим подробнее некоторые из новых возможностей WSE3. Во-первых, Microsoft предусмотрел набор готовых моделей безопасности, позволяющих использовать для обеспечения безопасности Web-сервисов методологии, основанные на шаблонах. Эти модели безопасности основаны на спецификациях WS* и позволяют применять стандартные для индустрии приемы, значительно сокращая время разработки. В WSE3 имеется пять готовых моделей безопасности: AnonymousOverCertificate, Kerberos, MutualCertificate, UsernameOverTransport и UsernameOverCertificate (см. таблицу 1). Выбор между ними состоит в выборе конфигурационного файла. В этой статье используется модель MutualCertificate.

Готовая модель
безопасности
Описание
AnonymousOverCertificate В этой модели любой анонимный клиент может использовать шифрование сообщений, используя серверный открытый сертификат X.509.
Kerberos Клиент и сервер используют токены Kerberos для шифрования сообщений и/или аутентификации. Это решения требует наличия Kerberos Domain Controller (KDC) или другого провайдера токенов.
MutualCertificate Эта модель обеспечивает аутентификацию и шифрование сообщений с помощью обмена сервера и клиента сертификатами X.509.
UsernameOverTransport Как следует из названия, аутентификация производится по паролю и имени пользователя, а шифрование сообщений производится с помощью SSL.
UsernameOverCertificate Как и в случае UsernameOverTransport, для аутентификации используется пароль и имя пользователя,но вместо SSL для шифрования используется серверный сертификат X.509.
Таблица 1. Выбор моделей безопасности в WSE 3.0.

WSE3 также содержит несколько улучшений фреймворка политик. Например, WSE3 создает синергию между императивной и декларативной моделями программирования; то, что вы делаете в коде с фреймворком политик, напрямую коррелирует с изменениями, которые вы производите в файлах конфигурации политик. Это дает реальную расширяемость политик. WSE3 также включает улучшенную систему атрибутов. Например, теперь можно снабдить сервис и клиент атрибутом политики [Policy("MyPolicyRocks")], и в WSE3 имеется визард, упрощающий создание таких файлов политик. Другие усовершенствования включают поддержку MTOM, WS-SecureConversation (улучшенное управление сессиями), поддержку 64-битной работы, .NET 2.0 и много другого. Полный список возможностей можно найти на сайте MSDN.

После установки WSE3, Visual Studio 2005 и SQL Server откройте SQL Server Enterprise Manager и создайте новую БД с названием WSE_Sample, а в ней – таблицу PDF_Files. В таблице должно быть две колонки: Filename (nvarchar (50)) и PDF (image (16)), первичным ключом должна быть колонка Filename.

Простая структура таблицы, использованной в примере, позволяет исследовать детали работы WSE3. Большинство реальных приложений будет иметь другие требования к колонкам, а также более сложную структуру таблиц. Создав БД, откройте Visual Studio 2005 и создайте новый Web-сервис, выбрав File | New | Web Site | Web Service. Назовите проект Web-сервиса "MTOM_WSE", и выберите HTTP.

После загрузки проекта переименуйте ASMX-файл и файл кода (code-behind) в SecureMTOM.asmx и SecureMTOM.cs, соответственно. В файле кода переименуйте класс и конструктор по умолчанию из "Service" в "SecureMTOMService". В классе SecureMTOMService нужно создать метод GetPDF, позволяющий новому сервису отправлять и получать данные, затем определить его возвращаемый тип как Byte[] и дать ему строковый параметр "filename". После этого создайте метод "InsertPDF" с возвращаемым типом void и двумя параметрами: типа string с названием "fileName" и типа Byte[] с именем "file". Логика реализации этих методов проста:

// Сигнатура первого метода для получения PDF
 [WebMethod]
public Byte[] GetPDF(string fileName) { }

// Сигнатура второго метода - для вставки PDF
 [WebMethod]
public void InsertPDF(string fileName, Byte[] pdfFile) { }

Оба метода используют SqlConnection для подключения к БД и объект SqlCommand (далее – команда) для исполнения запросов. Метод InsertPDF требует, чтобы вы добавили к объекту команды пару параметров – FileName и PDF. Параметр FileName использует тип SqlDbType.NVarChar, а PDF – тип SqlDbType.Image. Назначьте значениям этих параметров Command соответствующие значения параметров метода, и вызовите функцию ExecuteNonQuery(). Метод GetPDF подставляет параметр в SQL-запрос по месту (конкатенацией строк) вместо параметра команды. Он также использует SQLDataReader для чтения данных, возвращаемых SQL-запросом. После открытия SqlDataReader считайте первую строку и вызовите функцию GetBytes для считывания массива Byte, после чего верните этот массив вызывающей стороне (см. листинг 1).

Листинг 1.

Методы GetPDF и InsertPDF – единственные Web-методы в нашем Web-сервисе. Реализация проста, но эти два примера в комбинации с некоторыми конфигурациями WSE 3.0 демонстрируют незаурядную мощь использования MTOM и модели безопасности MutualCertificate.

 [WebMethod]
public void InsertPDF(string fileName, Byte[] pdfFile) 
{
  // Задайте свою строку подключения
  using (SqlConnection pdfConn = new SqlConnection(LOCAL_CONN))
  {
    SqlCommand addPDF = new SqlCommand("INSERT INTO PDF_Files "
      + "(Filename, PDF) Values(@Filename, @PDF)", pdfDataConn);
    addPDF.Parameters.Add("@Filename", SqlDbType.NVarChar, 50).Value = fileName;
    addPDF.Parameters.Add("@PDF",
      SqlDbType.Image, pdfFile.Length).Value = pdfFile;
    pdfDataConn.Open();
    addPDF.ExecuteNonQuery();
  }
}

[WebMethod]
public Byte[] GetPDF(string fileName) 
{
  // Задайте свою строку подключения
  using (SqlConnection pdfConn = new SqlConnection(LOCAL_CONN))
  {
    SqlCommand pdfCMD = new SqlCommand(
      "SELECT Filename, PDF FROM PDF_Files WHERE Filename ='"
      + fileName + "'", pdfConn);
    pdfConn.Open();

    using (SqlDataReader myReader = pdfCMD.ExecuteReader())
    {
      myReader.Read();

      byte[] blob = new Byte[(int)myReader.GetSqlBytes(1).Length];

      myReader.GetBytes(1, 0, blob, 0, (int)blob.Length);
      return blob;
    }
  }
}

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

Мы реализовали ядро сервиса. Следующий шаг – настройка безопасности и MTOM. Прежде чем зарыться в консоль WSE (интегрированную в Visual Studio 2005), нужно установить на локальной машине некоторые сертификаты. Вы можете сгенерировать собственные сертификаты, но Microsoft предоставил несколько тестовых сертификатов (созданных с помощью Makecert.exe) и включил их в примеры QuickStart, поставляемые с WSE 3.0 (по умолчанию путь C:\Program Files\Microsoft WSE\v3.0\Samples\Sample Test Certificates). Я не буду описывать по шагам процесс установки, поскольку инструкции имеются в readme-файле WSE 3.0. Предостережение: установите Server Cert.cer в хранилище сертификатов "other people" и убедитесь, что вы дали учетной записи ASP.NET соответствующие права (подробнее об установке примеров сертификатов см. http://pluralsight.com/blogs/aaron/archive/2004/07/13/1623.aspx).


Рисунок 1.

После установки сертификатов можно начать использовать WSE 3.0. Выберите из контекстного меню решения в Visual Studio 2005 "WSE Settings 3.0". Это вызовет новое окно с несколькими закладками: General, Security, Routing, Policy, TokenIssuing, Diagnostics и Messaging. Настройте Web-сервис на использование WSE3 с помощью WseProtocolFactory. Это можно сделать на закладке General, пометив "Enable this project for Web Services Enhancements" и "Enable Microsoft Web Services Enhancement Soap Protocol Factory". В результате будет сгенерирован класс WseProtocolFactory, а в файл web.config будут внесены соответствующие метаданные, см. рисунок 1.

Класс WseProtocolFactory перехватывает SOAP-сообщения и обрабатывает WS*-спецификации, указанные в SOAP-заголовке. После подключения WSE3 к Web-сервису перейдите на закладку Messaging и посмотрите на опции MTOM Settings. Для конфигурирования MTOM предусмотрено несколько настроек. Во-первых, можно настроить сервер на Always, Optional или Never; во-вторых, можно указать, включен или выключен клиент (On/Off). Настройка сервера на Always означает, что вся передача и прием данных будут MTOM-кодированы. Optional означает, что сервис будет использовать MTOM, но будет принимать и другие форматы передачи данных. Наконец, настройка сервера на Never означает, что сервер не использует MTOM. On/Off указывает, будут ли автогенерируемые клиентские прокси требовать MTOM.

Настройте клиент на On, а сервер на Always. Нажатие ОК добавит метаданные в файл web.config, заставит сервис принимать только MTOM и потребует от клиента посылать только MTOM-сообщения. Теперь нужно настроить безопасность и политику. Перейдите на закладку Policy окна WSE Settings 3.0, нажмите кнопку Add и введите имя "ServerPolicy". После нажатия ОК появится WSE Security Setting Wizard. Визард интуитивен и упрощает настройку готовых решений безопасности. Первое окно спрашивает, что нужно настраивать (клиент или сервер), следующее – какой тип безопасности вы хотите использовать (Anonymous, Username, Certificate или Windows). Выберите Certificate. На последних нескольких шагов требуется выбрать, кто может аутентифицировать, и указать, где находятся сертификаты. После этого визард создаст новый файл политики wse3policyCache.config, который и добавит в наше решение. Этот файл содержит в виде XML всю информацию о конфигурации, введенную с помощью визарда.

Задействуйте MTOM и готовую Security для Web-сервиса, снабдив класс SecureMTOMService атрибутом [Policy("ServerPolicy")]. Это указывает классу использовать файл политики, созданный визардом.

Клиентское приложение

Итак, мы создали Web-сервис, использующий MTOM и WS-Security. Но у нас все еще нет клиентского приложения для тестирования новой функциональности. Начните с добавления к решению нового Windows Form-проекта с названием WSE_Client. Дайте форме какое-нибудь осмысленное имя, например, MTOMTest, и добавьте три кнопки: btnGetPDF, btnSeleсtFile и btnInsert. Теперь добавьте текстовое окно txtFile и перетащите на форму элементы управления WebBrowser и OpenFileDialog (см. рисунок 2).

Это все с UI-control-ами. Теперь добавьте Web-ссылку на Web-сервис SecureMTOM. Работая с предварительными версиями, я предпочитаю выбирать Web-ссылку из "local machine", а не "current solution". Ранее вы создали ServerPolicy; теперь нужно сделать то же самое для клиента. Перейдите в WSE Settings 3.0 и включите поддержку WSE 3.0. Заметьте, что вы не можете включить SOAP Protocol Factory, так как это не ASP.NET Web-сервис.

Повторяйте те же шаги, что вы выполняли для сервера, пока не доберетесь до закладки Policy. На этой закладке нажмите Add и введите "ClientPolicy". Когда появится визард WSE Security, выберите режимы аутентификации "Secure a client" и "Certificate". На следующих шагах вас попросят указать месторасположение клиентского и серверного сертификатов. После этого визард обновит файл app.config и сгенерирует файл политики, так же, как при настройке сервера. При реализации обработчиков btnGetPDF и btnInsert вам придется создать экземпляр прокси Web-сервиса SecureMTOM. Если вы правильно настроили Web-сервис, в пространстве имен WSE_Client.localhost будет располагаться класс SecureMTOMServiceWse. Используйте его для создания экземпляра прокси. После создания прокси, установите свойство SoapVersion в значение SoapProtocolVersion.Default, задайте политику «ClientPolicy» вызовом SetPolicy() и установите свойство RequireMtom в true:


Рисунок 2. Использование MTOM-сервиса.

Рисунок 2. Использование MTOM-сервиса.
localhost.SecureMTOMServiceWse myService = 
  new localhost.SecureMTOMServiceWse();

myService.SoapVersion = SoapProtocolVersion.Default;
myService.SetPolicy("ClientPolicy");
myService.RequireMtom = true;

В конце метода обработчика нажатия кнопки btnGetPDF вызовите метод Web-сервиса GetPDF() для получения файла из БД. Он вернет массив байтов. После этого используйте объект FileStream для записи PDF-файла на диск и элемент управления WebBrowser для его отображения.

if (Path.GetExtension() != ".pdf")
{
  MessageBox.Show(
    "Please Enter the name of a PDF to retrieve in the text box");
  return;
}

string myFile = txtFile.Text;
byte[] blob = myService.GetPDF(myFile);

if (File.Exists(Application.StartupPath + @"\" + myFile))
    File.Delete(Application.StartupPath + @"\" + myFile);

using (
  FileStream fs = new FileStream(Application.StartupPath + @"\" + myFile,
  FileMode.Create, FileAccess.Write))
{
  fs.Write(blob, 0, blob.Length);
}

webBrowser1.Navigate(Application.StartupPath + @"\" + myFile);

Обработчик нажатия на кнопку btnInsert, напротив, использует FileStream и BinaryReader для чтения файла в массив байтов и передаче его Web-сервису посредством метода InsertPDF(). Вы можете сделать этот пример несколько ближе к реальной жизни, если позволите пользователю задавать путь к загружаемому на сервер файлу и имя считываемого с сервера файла через текстовое поле. Именно так и сделано в моем примере.

FileStream fs = new FileStream(
  txtFile.Text, FileMode.Open, FileAccess.Read);

using (BinaryReader br = new BinaryReader(fs))
{
  byte[] pdf = br.ReadBytes((int)fs.Length);
  localhost.SecureMTOMServiceWse myService = 
    new localhost.SecureMTOMServiceWse();

  myService.SoapVersion = SoapProtocolVersion.Default;
  myService.SetPolicy("ClientPolicy");
  myService.RequireMtom = true;
  
  char[] delimiter = @"\".ToCharArray();
  string[] fileName = txtFile.Text.Split(delimiter);

  myService.InsertPDF(fileName[fileName.GetUpperBound(0)], pdf);
  MessageBox.Show("PDF Inserted");
}

Вот и все об этом примере. Он прост, но он показывает путь к использованию функциональности безопасности в WSE 3.0. Некоторые идеи расширения этого примера включают использование безопасных сессий, потоков бинарных данных, создание более сложных файлов политик, использование Kerberos и других моделей безопасности, а также модификацию модели данных для большего соответствия реальным приложениям Web-сервисов.


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

Copyright © 1994-2016 ООО "К-Пресс"