WS-Security (WS-S) — это спецификация, которая определяет набор форматов для добавления безопасности в сообщения SOAP. Она позволяет подписывать, шифровать и создавать токены доступа для SOAP-сообщений. В контексте Delphi, особенно в версии XE8, поддержка WS-S может быть ограничена, но можно реализовать необходимые механизмы для работы с WS-S.
Подписывание тела сообщения
Для того, чтобы подписать тело сообщения SOAP в Delphi XE8, можно использовать следующий подход:
Изменение XML перед отправкой запроса: Можно переопределить метод THTTPRIO.BeforeExecute, который позволяет перезаписать содержимое XML перед отправкой запроса. Это дает возможность внести изменения в структуру SOAP-сообщения.
Вставка WS-Sec элементов: Вставьте необходимые элементы WS-Sec в SOAP-Header. Это включает в себя BinarySecurityToken и Signature, который содержит SignedInfo с указанием алгоритма подписи и ссылки на тело, которое нужно подписать.
Создание подписи: Для создания подписи потребуется реализовать алгоритм, который будет использовать соответствующий сертификат для подписания данных. В Delphi это можно сделать с помощью компонентов криптографии.
Пример кода
unit Unit1;
interface
uses
Winapi.Windows,
IdHTTP,
IdSSL,
IdBaseComponent,
IdCompHdr,
IdGlobal;
type
TForm1 = class(TForm)
private
{ Для поддержки владельцев форм... }
procedure FormCreate(Sender: TObject);
end;
TMySoapHeader = class(TSOAPHeader)
private
FMyCert: TIdCert;
function GetToken: string;
published
property MyCert: TIdCert read FMyCert write FMyCert;
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
uses
IdSSLOpenSSL,
IdBase64,
IdXMLDoc;
type
TMySoapHeader = class(TSOAPHeader)
private
function GenerateSignature: string;
public
constructor Create(AOwner: TComponent; const AContentId: string);
procedure Assign(AWSRequest: TIdHTTP; ADocument: TIdXMLDoc);
published
property MyCert: TIdCert read FMyCert write FMyCert;
end;
{ TForm1 }
procedure TForm1.FormCreate(Sender: TObject);
var
MyRequest: string;
MyResponse: string;
MyDocument: TIdXMLDoc;
MyHeader: TMySoapHeader;
begin
inherited;
MyHeader := TMySoapHeader.Create(Self, 'urn:example:token');
try
// Создаем запрос к веб-сервису
with TIdHTTP do
begin
// Устанавливаем URL для запроса
URI := 'http://example.com/soap';
// Устанавливаем метод запроса
Request := 'POST';
// Устанавливаем тип содержимого
ContentType := 'text/xml';
// Включаем SSL
Secure := True;
// Выполняем запрос к сервису
if TryConnect then
begin
// Отправляем SOAP-запрос
if not SendXML('<?xml version="1.0" encoding="UTF-8"?><SOAP-ENV:Envelope ...', True) then
raise Exception.Create('Ошибка отправки запроса.');
// Сохраняем ответ от сервера
MyResponse := Response.Text;
end;
// Перехватываем событие перед отправкой запроса
OnBeforeExecute :=
function
(AContext: Pointer;
var
var_Stream: TStream;
var_Content: Pointer;
var_ContentLen: NativeInt;
var_ContentType: string;
var_ContentDisposition: string;
var_ContentTransferEncoding: string;
var_ServerCert: Pointer);
begin
with TIdXMLDoc.Create(nil) do
try
// Загружаем XML из запроса
LoadXML(MyRequest);
// Находим Body в запросе
var BodyNode: TXMLNode;
Begin
BodyNode := FindNode('SOAP-ENV:Body');
except
on E: Exception do
begin
// Логика обработки ошибок
MessageDlg('Ошибка нахождения узла Body в запросе', mtError, [mbOK]);
Exit;
end;
end;
// Создаем заголовок безопасности
MyHeader := TMySoapHeader.Create(Self, 'urn:example:token');
MyHeader.MyCert := TIdCert.Create(nil);
// Загружаем сертификат
MyHeader.MyCert.LoadFromFile('path_to_cert.pem');
// Подписываем запрос
MyHeader.Assign(AContext, Self);
// Продолжаем обработку запроса
Writeln('Заголовок WS-Sec успешно создан и добавлен к запросу.');
finally
Free;
end;
end;
// Продолжаем нашу процедуру создания заголовка WS-Sec
// ...
// Функция генерации подписи
function TMySoapHeader.GenerateSignature: string;
begin
// Генерация подписи с использованием OpenSSL
// ...
end;
// Конструкор
constructor TMySoapHeader.Create(AOwner: TComponent; const AContentId: string);
begin
inherited;
ContentId := AContentId;
end;
// Переопределение метода Assign для добавления заголовка в запрос
procedure TMySoapHeader.Assign(AWSRequest: TIdHTTP; ADocument: TIdXMLDoc);
var
MySecurityHeader: TXMLNode;
begin
// Генерация XML для WS-Sec заголовка
// ...
end;
end;
end;
Заключение
Приведенный пример демонстрирует, как можно реализовать механизм подписи тела SOAP-сообщения в Delphi XE8 с использованием WS-Security. Обратите внимание, что для полноценной реализации потребуется написать дополнительные функции, такие как генерация и добавление в XML подписи и токенов безопасности.
Создание WS-Security для SOAP в Delphi XE8 включает в себя подход к подписыванию тела сообщения путем внесения изменений в XML перед отправкой запроса и добавления элементов WS-Sec в SOAP-Header.
Комментарии и вопросы
Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS
Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.