6) безопасность в веб-сервисах –

How to configure axis framework for authentication using the “wsse” security standard in sap pi | sap blogs

How to Configure AXIS Framework for Authentication Using the “wsse” Security Standard in SAP PI 

Introduction

You might be required to consume an interface exposed as a web service from a provider system using the receiver SOAP Adapter (SOAP/HTTP) connection. The provided service is therefore consumed via the provided soap endpoint.

In order to consume a service which requires “wsse” standard for authentication, there exists different options for implementing this. But in this blog, the focus is on the configuration of the “wsse” standard using the axis framework.

In “wsse” standard, a WS-SecurityUsername Tokenenables an end-user identity to be passed over multiple hops before reaching the destination Web Service. The user identity is inserted into the message and is available for processing at each hop on its path. The client user name and password are encapsulated in a WS-Security<wsse:UsernameToken>.

   /wp-content/uploads/2022/04/image1_204908.jpg                   

Figure 1: Structure of SOAP message with “wsse” header

Create Communication Channel: To use this functionality, the Axis framework and all the necessary jar files must have been deployed on the PI system. Below are the steps necessary to implement security in the header of the message.

a)      Create a communication channel, under the parameter tab, choose the adapter SOAP and tick the receiver button;

b)      Choose the transport protocol as HTTP (Axis) and message protocol axis is automatically inserted in that field.

c)      Enter the appropriate URL, and under XI Paramter, tick the XI header option and if a SOAP Action is required, enter the value for it.

  /wp-content/uploads/2022/04/1_204909.jpg

Figure 2: Receiver SOAP Adapter with AXIS message protocol

Axis Framework Configuration:In order to configure the Axis framework, switch to the module tab on the communication channel and enter the parameters shown in the screen below in the order specified in the screen.

Processing Sequence

ModuleName:  AF_Adapters/axis/HandlerBean

Type: Local Enterprise Bean

ModuleKey: wssec

Module Configuration

/wp-content/uploads/2022/04/image003_204910.jpg

Figure 3: AXIS module configuration for “wsse”

Note: the parameters name and parameters value are case sensitive, so care should be taken they are entered as described above, if not the Adapter engine will throw up an error when the communication channel is monitored from the runtime workbench

References:  For further references, please check the FAQ note 1039369

Vbnet – статьи – ws-security аутентификация и цифровые подписи с помощью web services enhancements

Среда WSE

WSE располагается на вершине поддержки, предоставляемой .NET Framework для
написания и потребления Web сервисов. В центре WSE поддержки находится класс
Microsoft.Web.Services.SoapContext, обеспечивающий интерфейс
для проверки заголовка WS-Security и других заголовков в поступающих SOAP
сообщениях и добавления заголовка WS-Security и других заголовков в исходящие
SOAP сообщения. Для разработчиков, пишущих код для потребления Web сервисов, был
создан интерфейсный класс, чтобы путем добавления SoapContext
для SOAP запроса и ответа усовершенствовать возможности оболочки. На сервере
было создано Microsoft ASP.NET SOAP расширение, которое проверяет достоверность
поступающих SOAP сообщений и создает запрос и ответ
SoapContext, к которому можно доступиться из WebMethods.

Настройка основной среды WSE влечет за собой конфигурирование вашего ASP.NET
приложения для использования расширения WSE SOAP. Это возможно на базе многих
машин путем добавления некоторых данных в Machine.config, но
возможны случаи, когда вам не понадобится или вы не захотите поддержки WSE. Мы
будем добавлять поддержку WSE для конкретной виртуальной директории. Чтобы
сделать это, добавьте элемент
/configuration/system.web/webServices/soapExtensionTypes/Add в
Web.config для вашей виртуальной директории. Добавленный элемент должен
выглядеть примерно так, как представлено ниже, лишь с тем исключением, что
атрибут type должен весь помещаться в одну строку (здесь он разбит для
читабельности).

<webServices>
  <soapExtensionTypes>
    <add type="Microsoft.Web.Services.WebServicesExtension, 
        Microsoft.Web.Services, Version=1.0.0.0, Culture=neutral, 
        PublicKeyToken=31bf3856ad364e35" priority="1" group="0" />
  </soapExtensionTypes>
</webServices>

С точки зрения WSE, теперь мы готовы следовать дальше. Будут еще
дополнительные настройки конфигурации, которые нам понадобится сделать для
определенных аспектов WS-Security, мы обсудим их позже. Сейчас, все что нам надо
сделать – это добавить ссылку на Microsoft.Web.Services.dll в
наш Visual Studio .NET проект, и мы готовы.

Базовая аутентификация имя-пользователь – маркер
(UsernameToken)

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

Элемент UsernameToken определен в WS-Security, чтобы
обеспечить средства для проведения базовой проверки достоверности имени
пользователя/маркера. Если у вас есть опыт с HTTP, вы можете сравнить сходство
этой системы с базовой аутентификацией (Basic Authentication). WS-Security
предоставляет несколько вариантов через три формы элемента
UsernameToken. Различные формы показаны ниже:

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

Чтобы обойти эту проблему, Web Services Security
Addendum
(http://msdn.microsoft.com/webservices/building/security/default.aspx?pull=/library/en-us/dnglobspec/html/ws-security-addendum.asp)

добавил дополнительные защитные меры. Вместо того, чтобы отправлять просто хеша
пароля, приложение определяет, что должна быть отправлена цифровая версия
пароля. Эта цифровая версия содержит хеш, который является комбинацией пароля,
Nonce (функционально уникальной строки, которая идентифицирует
этот запрос) и времени создания. Следовательно, невозможно существование двух
одинаковых хешей пароля. Версия Revised UsernameToken приведена
ниже:

Хотя у каждого легитимного запроса будет отличный от других хэш, вам надо
быть осторожными со злонамеренными пользователями, вытягивающими целый
UsernameToken из чьего-то легитимного запроса и помещающими его
в собственные нелегитимные ответы. Вы можете минимизировать риск, задавая
достаточно малый срок действия Временной метки (Timestamp) (еще одна возможность
WSE) и логически уменьшать срок действия на сервере. Например, возможно, вы
захотите показать, что срок действия сообщения закончится через 30 секунд, таким
образом оно не будет переходит в режим отсрочки, а на сервере через 30 секунд от
времени, указанного в элементе Created,
UsernameTokens не будет приниматься. Помните, что проблемы
синхронизации часов между машинами могут обусловить проблемы непринятия
действительных запросов и, в определенных ситуациях, принятия простроченных
запросов. Таким образом, использование времени создания не решает всей проблемы.
Чтобы еще более исключить риск, Web сервис может сохранять таблицу значений
Nonce от недавно полученных UsernameTokens и
не давать разрешение на ответ, если Nonce уже использовался
ранее. В таблицу будут входить только текущие сообщения и находится там до
истечения срока их действия. Если вы получили несколько запросов с одинаковым
Nonce, вы должны отвергнуть их все, поскольку возможно, что
нелегитимный запрос был получен первым. Также помните, что проверка
Nonce не спасет в случае, когда злонамеренный посредник
перехватывает поступающие сообщения и заменяет их своими, используя
UsernameToken исходного сообщения. Чтобы защититься от такого
рода атак, вам понадобится добавить цифровую подпись. Чуть позже в этой статье
мы рассмотрим цифровые подписи.

Конечно же вся эта хэш-защита не исключает того факта, что и отправитель, и
получатель должны знать пароль пользователя. Со стороны клиента закономерно, что
пользователям пароли могут быть подсказаны. Со стороны сервера, однако,
необходима некоторая таблица, в которой можно посмотреть действительные пары имя
пользователя/пароль. В WSE это возможность обеспечивается через механизм
расширения, называемый Провайдером пароля (Password Provider).

Провайдер пароля (Password Provider)

WSE определяет интерфейс
Microsoft.Web.Services.Security.IPasswordProvider в качестве
класса, который надо реализовать, чтобы зарегистрироваться как Провайдер пароля.
В интерфейсе есть одна функция, GetPassword, и в качестве
входных данных они принимает
Microsoft.Web.Services.Security.UsernameToken. Функция
GetPassword возвращает пароль для данного пользователя. Идея в
том, что для сохранения действительных пар имя пользователя/пароль вы можете
использовать любой механизм, какой пожелаете, а затем обеспечивать класс,
реализовывающий интерфейс IPasswordProvider, чтобы обеспечить
WSE возможность доступаться к вашему конкретному механизму сохранения пароля. У
вас есть также вариант осуществления собственной комбинации цифр и хэшей в
UsernameToken, возможно с совместно используемым секретом, в
целях дальнейшего контроля вашей инфраструктуры аутентификации.

Чтобы передавать данные в WSE вашего конкретного Провайдера пароля, вы должны
задать соответствующие установочные параметры конфигурации WSE. Это требует
добавления элемента microsoft.web.services в файл конфигурации
вашего приложения. Также это влечет за собой необходимость определения WSE
класса, который может понимать именно эту информацию конфигурации. Приведенный
далее configSections может быть добавлен в Machine.config или
конкретный Web.configs на вашей машине. Опять же, атрибут type должен весь
помещаться в одной строке, но в данном случае он разбит в целях читабельности.
Этот узел размещен в /configuration/configSections в вашем .config файле.

<configSections>
  <section name="microsoft.web.services"
    type="Microsoft.Web.Services.Configuration.WebServicesConfiguration,
    Microsoft.Web.Services, Version=1.0.0.0, Culture=neutral, 
    PublicKeyToken=31bf3856ad364e35" />
</configSections>	
			

Для ASP.NET приложения в качестве потомка элемента родительской конфигурации,
чтобы проинформировать WSE вашего конкретного Провайдера пароля, в Web.config
могут быть добавлены следующие входные данные:

В атрибуте type элемента passwordProvider
указан написанный вами класс, который реализует интерфейс
IPasswordProvider. В данном случае, мой класс называется
PasswordProvider, определен он в пространстве имен
WSE_Security и размещен в сборке WSE-Security.dll. Ради
простоты, мой класс возвращает пароль “opensezme” для всех имен пользователей. В
большинстве сценариев именно здесь вы должны реализовать логику, которая
считывает соответствующий пароль из SQL базы данных или какого-нибудь другого
хранилища. Код для моего обычного класса приведен ниже:

Создание WebMethod, использующего WS-Security

Теперь мы действительно готовы к созданию Web сервиса и его вызову. Web
сервис, который я хочу создать, будет простым Web сервисом типа “Hello World”,
за исключением того, что я хочу доступаться к SoapContext для
класса, чтобы иметь возможность персонализировать ответ. Код для моего WebMethod
показан ниже:

До того, как я смогу что-либо сделать с WSE в моем WebMethod, в своем проекте
я должен добавить ссылку на Microsoft.Web.Services.dll. Затем я добавляю в код
для Microsoft.Web.Services и
Microsoft.Web.Services.Security два оператора
using. Теперь я могу создать свой
PersonalHello WebMethod.

Первое, что делает моя функция PersonalHello – с помощью
статического члена HttpSoapContext.RequestContext выбирает
объект SoapContext для запроса. Теперь я могу доступаться ко
всей информации заголовков WS-Security. Если в них нет контекста, мой Web метод
возвращает значение Fault, в противном случае, я пронумеровываю
все маркеры доступа, которые посылаю со своим запросом, и проверяю, не является
ли один из них UsernameTokens. Если я нахожу
UsernameToken, я создаю строку ответа, которая включает
приветствие, в которое входит имя пользователя.

Создание клиента, использующего WS-Security

Чтобы увидеть, как воспользоваться преимуществами WS-Security с WSE со
стороны клиента, я создал простое приложение Windows Form, которое будет
вызывать мой Web сервис по нажатию кнопки. Так же, как я делал это для класса
моего Web сервиса, я добавил ссылку на Microsoft.Web.Services.dll и включил
такие же выражения using, как мы добавляли в коде нашего
сервера.

Для клиентской стороны WSE предоставляет класс
Microsoft.Web.Services.WebServicesClientProtocol, который
наследуется от класса
System.Web.Services.Protocols.SoapHttpClientProtocol. Класс
SoapHttpClientProtocol используется, когда для создания кода
клиента на основе WSDL вы выбираете опцию Add Web Reference в
Visual Studio .NET или используете утилиту WSDL.exe. Все, что я могу сделать –
использовать или опцию Add Web Reference из Visual Studio .NET,
или утилиту WSDL.exe, чтобы сгенерировать прокси классы для вашего клиента,
затем заменить родителя сгенерированного прокси класс с
SoapHttpClientProtocol на
WebServicesClientProtocol. Теперь прокси класс будет иметь
свойства RequestSoapContext и
ResponseSoapContext, которые вы можете использовать для доступа
к отправляемым и получаемым вами заголовкам WS-Security. Если вы используете
опцию Add Web Reference, вы найдете код для сгенерированного
прокси класса в директории Web References. Для проектов C# вы найдете файл
Reference.cs в директории, имя которой совпадает с именем хоста, в котором
находится WSDL. Для проектов Microsoft® Visual Basic® .NET файл называется
Reference.vb. Я заменил описание типа

на

public class Service1 : 
    Microsoft.Web.Services.WebServicesClientProtocol {
			

Если вы используете опцию Visual Studio .NET Add Web
Reference
, вам надо быть аккуратными при внесении изменений в файл, в
котором размещается генерируемый код. Если вы выбираете опцию Update Web
Reference
, Visual Studio .NET регенерирует код и перезаписывает ваши
изменения.

Для создания UsernameToken для запроса код моего клиента
выглядит следующим образом.

Единственное различие между этим кодом и кодом, который будет вызывать
обычный Web сервис, в том, что я создал объект UsernameToken и
добавил его в коллекцию Tokens для запроса. Конструктор для объекта
UsernameToken принимает три параметра: имя пользователя, пароль
и PasswordOption. В данном случае я посылаю хэшированный пароль. Краткая версия
SOAP запроса, сгенерированного из этого кода, показана ниже. Вы заметите, что
заголовок Security включен в запрос, в который входит дочерний элемент
UsernameToken, содержащий имя пользователя, хэшированный
пароль, случайный Nonce, который мы можем использовать для
идентификации этого конкретного запроса, и время создания. Все сообщение
приведено в конце этой статьи с разделе Ссылки.

Теперь сообщение может быть отправлено Web сервису, где WSE SOAP расширение
будет проверять достоверность запроса, сравнивать хэш пароля с паролем,
полученным от Провайдера пароля, и затем, если все пройдет хорошо, запрос
передастся в наш Web метод. Наш Web метод получает поступающий запрос с
заполненным SoapContext, в заголовке Security ищет
UsernameToken и создает строку ответа на базе полученного
имени. Ответ возвращается как обычный WebMethod ответ, и наше клиентское
приложение отображает возвращенную строку. Мы успешно выполнили наше первое
WS-Security приложение!

Проверка достоверности UsernameToken на сервере

Хотя WSE проверяет достоверность синтаксиса заголовка Security и сравнивает
хэш пароля с паролем из Провайдера пароля, для запроса должны быть проведены еще
некоторые дополнительные проверки. Например, в запрос может быть включен не один
элемент UsernameToken. WS-Security предоставляет поддержку для
включения в запрос любого количества маркеров, которые могут использоваться в
разных целях. Тот факт, что в коде нашего клиента добавляется
UsernameToken в коллекцию Tokens, должен быть четким
предупреждением, что в одно сообщение может входить больше одного. Кстати, если
вы изменили код клиента, чтобы создать второй UsernameToken и
добавить его в коллекцию, наш текущий код вернет строку, подобную следующей:

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

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

Хранилища сертификатов

До того как мы сможем включить сертификат в наш запрос, мы должны определить,
где найти его. В традиционной разработке программного обеспечения Microsoft®
Windows сертификаты сохранялись централизованно в так называемом хранилище
сертификатов. У каждого пользователя было персональное хранилище сертификатов,
чтобы осуществлять такие вещи, как формирование цифровых подписей для сообщений
электронной почты или аутентификация Web серверами через SSL. Сами сертификаты
не являются персональными, поскольку они – просто способ выдачи открытых ключей.
Важно то, что секретный ключ, соответствующий открытому ключу в сертификате,
находится в защищенном хранилище ключей лица, чей сертификат используется. Это
позволит пользователям создавать цифровые подписи для категорий с помощью своих
секретных ключей, а затем кто угодно сможет проверить достоверность их подписи с
помощью открытого ключа сертификата.

В первоначальной версии .NET Framework не было классов для доступа к
хранилищам Windows сертификатов, хотя были классы для обработки X.509
сертификатов. Впрочем, WSE предоставил классы, которые позволяют вам открывать
хранилища Windows сертификатов и использовать сертификаты из этого свободно
управляемого пространства. В следующем коде для заполнения
ListBox общими именами всех сертификатов в персональном
хранилище сертификатов пользователя используется класс
Microsoft.Web.Services.Security.X509.

Пример полнофункционального диалога для выбора X.509 сертификата из хранилища
сертификатов приведен в X509CertificateStoreDialog.cs директории примеров кода
WSE.

Добавление маркера сертификата X.509 в SOAP
сообщение

Теперь, когда мы можем найти наш персональный сертификат, процесс их
добавления в SOAP запрос очень похож на добавление
UsernameToken, используемого нами ранее. Следующий код получает
сертификат из уже открытого хранилища сертификатов из ListBox,
заполненного нами ранее, и затем добавляет двоичный маркер, созданный из
сертификата, в коллекцию Tokens.

X509Certificate cert =
    (X509Certificate)store.Certificates[listBox1.SelectedIndex];
proxy.RequestSoapContext.Security.Tokens.Add(
    new X509SecurityToken(cert));			
			

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

Цифровые подписи

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

WSE открыто поддерживает создание цифровых подписей. Наряду с коллекцией
Tokens, здесь есть коллекция SoapContext.Security.Elements, которая позволит вам
добавлять различные элементы WS-Security, включая элемент
Signature. Основываясь на нашем предыдущем коде клиента,
который включает цифровой сертификат, теперь мы используем этот же сертификат
для подписания запроса:

X509Certificate cert = 
    (X509Certificate)store.Certificates[listBox1.SelectedIndex];
X509SecurityToken certToken = new X509SecurityToken(cert);
proxy.RequestSoapContext.Security.Tokens.Add(certToken);
proxy.RequestSoapContext.Security.Elements.Add(
    new Signature(certToken));			
			

Так же как мы делали ранее, мы извлекаем сертификат из предварительно
открытого хранилища сертификатов и добавляем его в коллекцию Tokens. Затем,
используя X509SecurityToken в качестве параметра для
конструктора Signature, мы создаем новый объект Signature и
добавляем его в коллекцию Elements. Сокращенная версия SOAP сообщения,
генерируемого из этого кода, показана ниже. Полностью SOAP сообщение приведено в
конце этой статьи.

Для полного понимания различных элементов заголовка, включенных в этот
запрос, ознакомьтесь со спецификациями WS-Routing
(http://msdn.microsoft.com/webservices/building/security/default.aspx?pull=/library/en-us/dnglobspec/html/ws-routing.asp)

и Web Services Security Addendum
(http://msdn.microsoft.com/webservices/building/security/default.aspx?pull=/library/en-us/dnglobspec/html/ws-security-addendum.asp)
.
Для нашего обсуждения мы рассмотрим особенности того, как WSE использует
WS-Security для подписания нашего запроса.

Первое, что надо отметить по поводу этого сообщения – это то, что здесь в
заголовке Security есть элемент BinarySecurityToken. Атрибуты
этого элемента показывают, что это Base 64 кодированный сертификат X.509 v3. Это
X509SecurityToken, который мы добавили в коллекцию Tokens в
наших двух последних примерах. И опять же, вовсе не обязательно включать его в
сообщение, но это удобно для проверки достоверности подписи.

Следующее, на что надо обратить внимание – это то, что теперь элемент
Signature находится в заголовке Security. У Signature есть три
дочерних элемента: SignedInfo, SignatureValue
и KeyInfo. Элемент SignedInfo определяет
конкретные данные, подписанные в этом запросе, как они были канонизированны и
какой алгоритм использовался для вычисления подписи. Важно понять список
используемых элементов, который определяет, что конкретно в этом элементе было
подписано. Для краткости я удалил некоторое количество используемых элементов,
но вы заметите, что у каждого из двух оставшихся есть ассоциированный атрибут
URI. Этот атрибут URI соответствует атрибуту ID элемента, включенному в подпись.
Например, в первой ссылке показан URI, начинающийся с “#Id-24cc3660-“. Если вы
просмотрите сообщение, вы увидите, что этот URI соответствует ID для элемента
Body нашего сообщения. Поэтому Body является
частью пописанной информации для этого запроса. Вторая ссылка касается элемента
action заголовка Path, который является частью спецификации
WS-Routing. WSE автоматически включает заголовки Path и Timestamp, и большинство
дополнительной информации этих заголовков включается в цифровую подпись. Далее
приведен список элементов, на которые WSE будет ссылаться в заголовке
SignedInfo, и которые, таким образом, будут включены в цифровую подпись.

/soap:Envelope/soap:Header/wsrp:path/wsrp:action
/soap:Envelope/soap:Header/wsrp:path/wsrp:to
/soap:Envelope/soap:Header/wsrp:path/wsrp:from
/soap:Envelope/soap:Header/wsrp:path/wsrp:id
/soap:Envelope/soap:Header/wsu:Timestamp/wsu:Created
/soap:Envelope/soap:Header/wsu:Timestamp/wsu:Expires
/soap:Envelope/soap:Body			
			

Причина, по которой подписаны подэлементы заголовков path и Timestamp, а не
полностью элементы path и Timestamp, в том, что в сценариях WS-Routing
ожидается, что посредники будут добавлять элементы в заголовки path и Timestamp
по мере передачи сообщения через маршрутизаторы уровня SOAP. Поэтому, если бы
какой-нибудь из этих заголовков был бы изменен, цифровая подпись разрушилась
бы.И последнее по поводу элемента Signature в этом запросе – в
KeyInfo есть ссылка на BinarySecurityToken,
содержащий наши сертификаты. Он показывает, откуда поступил ключ, который
использовался для подписания нашего запроса. Конечно же, для сертификата – это
секретный ключ, соответствующий открытому ключу в сертификате, который
использовался для создания цифровой подписи. Затем открытый ключ может
использоваться для проверки достоверности того, что данные могут поступать
только от того, кто знает соответствующий секретный ключ.

Проверка достоверности цифровой подписи

Проверять достоверность синтаксиса цифровой подписи будет WSE SOAP
расширение, но простого знания того, что подпись в сообщении достоверна, не
достаточно для определения, что сообщения поступило от конкретного лица.
WS-Security и спецификация XML Digital Signature, (Extensible Markup Language) XML-Signature Syntax and
Processing (http://www.ietf.org/rfc/rfc3275.txt)
, очень гибки в
том смысле, что они обеспечивают возможность включать подписи в XML. Например,
вы ожидаете сообщение от Alice, вы, возможно, видите, что сообщение имеет
подпись от Alice, но эта подпись может подписывать только маршрутную информацию
заголовка path. Пока вы не провели некоторые собственные проверки, нет гарантии
того, что интересующие вас вещи (обычно тело сообщения) поступили от Alice.

Следующий код ищет Signature в запросе, проверяет то, что тело сообщения
подписано с помощью свойства SignatureOptions и затем, когда мы
точно знаем, кто послал сообщение, и что оно пришло таким же, каким было
отправлено, создает индивидуальное приветствие на основании сертификата,
используемого для подписания запроса.

Подпись части сообщения

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

У вас есть два варианта для определения того, какие части сообщения
охраняются цифровой подписью. В предыдущем примере мы пользовались свойством
SignatureOptions класса Signature, чтобы
определить, включает ли подпись SOAP тело. Вы также можете применять свойство
SignatureOptions, чтобы установить, какие части SOAP сообщения
должны быть защищены подписью. Вы можете использовать любую комбинацию следующих
флагов, определенных перечнем SignatureOptions:

IncludePath
IncludePathAction
IncludePathFrom
IncludePathId
IncludePathTo
IncludeSoapBody
IncludeTimestamp
IncludeTimestampCreated
IncludeTimestampExpires			
			

Есть еще одно значение, которое вы можете задать для
SignatureOptionsIncludeNone. Оно
показывает, что ни один из приведенных выше вариантов не должен быть включен в
подпись. Тогда зачем все эти беспокойства по поводу подписания сообщения, если
вы собираетесь задать SignatureOption значение
IncludeNone? Ответ можно найти, используя другой механизм
определения того, какие части сообщения мы хотим отправить.

Для установления того, что подписывается, а что нет, WS-Security предлагает
два варианта. Первый – определить преобразование сообщения и затем на базе
результатов создать подпись. Другая возможность – задать атрибут
Id в элементе, который вы хотите подписать, и затем включить
ссылку на этот элемент в блоке SignedInfo элемента
Signature. Так WSE создает свои подписи для различных
вариантов, приведенных в перечне SignatureOptions. Но WSE также
позволяет вам создавать атрибут Id самостоятельно и затем
вручную добавлять ссылку в блок SignedInfo подписи. Это
обеспечивает вам возможность подписывать специальные SOAP заголовки так же, как
и любые отдельные части тела, которые вы хотите подписать. Вам только надо
гарантировать, что атрибут Id задан и что href
для него включен в ссылки. Мы рассмотрим пример, в котором подпишем только часть
SOAP тела.

Для создания и синтаксического анализа отправляемых и получаемых SOAP
сообщений ASP.NET Web сервисы используют XmlSerializer из .NET Framework. Вы
можете контролировать многие детали того, как конкретно происходит сериализация,
путем задания атрибутов, которые контролируют работу XmlSerializer. Поскольку не
сложно добавить атрибут Id для части XML, задайте его значение
и затем добавьте это значение в ссылки подписи.

Чтобы проиллюстрировать, как это сделать, я создал ASP.NET WebMethod,
возвращающий комплексный тип, который включает заказ. Я хочу создать цифровую
подпись только для элемента заказа, чтобы клиент знал наверняка, что он поступил
от меня. Сначала мы создаем комплексный класс, который будем возвращать из
нашего WebMethod. В этом класса есть номер действительного заказа, но также там
есть свойство ID, которое будет сериализовано как атрибут. На этот ID будет
ссылаться наша подпись. Важно, чтобы мы включили верное пространство имен для
этого атрибута, которое совпадает с пространством имен в спецификации
WS-Security, поэтому мы используем параметр Namespace атрибута
XmlAttribute, чтобы задать
http://schemas.xmlsoap.org.ws/2002/07/utility.

Наш WebMethod должен будет сделать несколько вещей. Во-первых, ему надо будет
сгенерировать GUID, который будет использоваться как уникальный ID. Он должен
будет создать экземпляр приведенного выше класса и задать свойство ID в формате,
соответствующем включенному значению GUID. Он также задает значение номера
действительного заказа, который в нашем конкретном случае всегда одинаковый.
Далее он создаст маркер доступа на базе сертификата X.509, который будет
использоваться для подписания номера заказа.

Чтобы использовать сертификат из ASP.NET, он должен быть в хранилище
сертификатов, доступном из рабочего процесса ASP.NET. Аналогично, секретный
ключ, соответствующий открытому ключу в сертификате, должен находится в
хранилище ключей, доступном из ASP.NET. Для моего примера я использовал
сертификат из хранилища сертификатов машины. Чтобы получить возможность работать
с ним, я предоставил полномочия “ASPNET пользователя” (учетная запись, под
которой которой запускается рабочий процесс ASP.NET) физическому хранилищу
ключей машины. Это потенциально открывает доступ к хранилищу ключей машины для
других приложений, поэтому вы должны делать такого рода изменения с предельной
осторожностью. Более подробная информация по проблемам хранения и доступа к
сертификатам и ключам на вашей машине представлена в документации WSE “Managing
X.509 Certificates”.

Имея маркер доступа, передавая его в конструктор мы можем создать экземпляр
Signature. Мы сразу задаем свойство SignatureOptions для
SignatureOptions.IncludeNone таким образом, чтобы он не включал
все применяемые по умолчанию части сообщения. Теперь мы вызываем метод
AddReference объекта Signature, задавая такую же строку, какую
мы задавали ранее для свойства ID, за исключением стоящего впереди символа ‘#’,
чтобы показать, что это локальная ссылка. Код для Web метода показан ниже:

Последний шаг –клиент проверяет соответствие подписи в возвращенном заказе.
Мы делаем это, сверяя возвращаемый ID с ссылками для подписи, и проверяя, что
используемый для этой подписи сертификат тот, который мы ожидали. Код для вызова
Web сервиса и проверки используемого сертификата показан ниже.

localhost.Service1Wse proxy = new localhost.Service1Wse();
localhost.PONum po = proxy.GetPONumber();
foreach (Object element in proxy.ResponseSoapContext.Security.Elements)
{
    if (element is Signature)
    {
        Signature sig = (Signature)element;
        foreach (Reference reference in sig.SignedInfo.References)
        {
            if (reference.Uri == "#"   po.Id)
            {
                X509Certificate signatureCert 
                    = ((X509SecurityToken)
                            sig.SecurityToken).Certificate;
                if (signatureCert.Equals(poCert))
                    MessageBox.Show("It's signed!");
            }
        }
    }
}			
			

Заключение

Эта статья предлагает вам ознакомится с возможностями спецификации
WS-Security через Web Services Enhancements для Microsoft .NET, путем
рассмотрения того, как вы можете использовать WSE для проведения аутентификации
UsernameToken, и используя аутентификацию X.509 для создания цифровой подписи
частей SOAP сообщения. WSE позволяет вам изучить и проверить вид WS-Security
поддержки, которая включена в SOAP сообщение. Существует большое количество
возможностей WS-Security, предоставляемых WSE и не осужденных здесь, например,
использование различных форм кодирования. Я рекомендую вам инсталлировать WSE,
написать кое-какой код и проверить созданные сообщения и сообщения, включенные в
раздел References, чтобы получить представление о том, как WS-Security может
увеличить функциональность ваших Web сервисов.

Похожее:  Как зарегистрироваться в Ощад24/7, инструкция - Управление финансами 2020

Добавить комментарий

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