Добавление неявных заголовков SOAP в WSDL

Мой вопрос подобен этому. Как передать заголовок мыла, когда WSDL не определяет его? Но это другое.

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

Я попытался указать заголовок SOAP в WSDL, но мне не удалось получить правильные пространства имен. WSDL здесь https://stage.totalcheck.sensis.com.au/service/webservice?wsdl, а заголовок SOAP выглядит следующим образом:

    <soapenv:Header>
        <wsse:Security>
            <wsse:UsernameToken>
                <wsse:Username>username</wsse:Username>
                <wsse:Password>password</wsse:Password>
            </wsse:UsernameToken>
        </wsse:Security>
   </soapenv:Header>

Может кто-нибудь мне помочь? Спасибо!

Ответы

Ответ 1

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

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

Таким образом, недостающая часть теперь является стандартом, который позволяет устанавливать некоторые нефункциональные требования к службам WSDL, чтобы генераторы кода могли автоматически выводить, какие заголовки должны быть отправлены и/или понимать, чтобы выполнить нефункциональное свойство по желанию - без необходимости вручную обрабатывать поля заголовка. Этот стандарт существует и называется WS-Policy. Политика содержит, как правило, набор альтернатив, которые предоставляют набор требований, которые должны выполнять как поставщик, так и потребитель. Когда две службы должны взаимодействовать друг с другом, принимаются обе стратегии и рассчитывается так называемая "эффективная политика". Он определяет общие нефункциональные требования. Используя эту информацию, поставщик и потребитель могут настроить себя для добавления необходимых заголовков, таких как заголовки WS-Security. WS-SecurityPolicy также определяет набор политик, которые можно использовать. WS-PolicyAttachment определяет, как такие политики могут быть привязаны к WSDL.

Существуют генераторы кода, которые могут работать с WS-политиками, например. Метро или Axis2

Ответ 2

Вы можете добавить информацию заголовка мыла к вызовам методов, украсив методы в прокси-классе, сгенерированном из wsdl, с помощью атрибута SoapHeader.

Например, wsdl.exe будет генерировать клиентский прокси-класс Reference.cs для ссылки на веб-службу при использовании "Добавить веб-ссылку". В ссылке, упомянутой выше https://stage.totalcheck.sensis.com.au/service/webservice?wsdl, появляется сообщение suggestAddress, которое будет переводить на метод в сгенерированном файле кода прокси файла reference.cs, когда вы добавьте веб-ссылку из visual studio. По умолчанию, когда этот метод вызывается, в конверте мыла не будет заголовка. Чтобы добавить SoapHeader к конверту для этого запроса, добавьте атрибут [SoapHeader ( "Security" )] в начало метода SuggestAddress в сгенерированном классе Reference.cs, где "Безопасность" - это класс, который наследуется от базового класса SoapHeader.

Пример для вышеописанного Security SoapHeader вы создали бы следующие классы,

public partial class Security : SoapHeader
{
    public UserNameToken UserNameToken { get; set; }
}

public partial class UserNameToken
{
    public string UserName { get; set; }
    public string Password { get; set; }
}

Затем вы должны украсить метод SuggestAddress в reference.cs, например,

[SoapHeader("Security")]
public suggestAddressesResult suggestAddresses([System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Schema.XmlSchemaForm.Unqualified)] addressSearch search) {
        object[] results = this.Invoke("suggestAddresses", new object[] {search});
        return ((suggestAddressesResult)(results[0]));
    }

Это гарантирует, что каждый конверт, созданный при вызове метода suggestAddress, содержит заголовок безопасности, который похож на тот, который указан выше,

<soapenv:Header>
    <wsse:Security>
        <wsse:UsernameToken>
            <wsse:Username>username</wsse:Username>
            <wsse:Password>password</wsse:Password>
        </wsse:UsernameToken>
    </wsse:Security>

Ответ 3

Ключ для меня в использовании этого вопроса, чтобы помочь себе, был признан (как некоторые отметили), что заголовки, о которых идет речь, относятся к стандарту WS-Security.

Если ваш инструмент создания прокси-сервера является "обычным", кажется логичным, что у вас может быть переключатель для автоматического добавления заголовков для WS-Security. Однако, если вы используете WSDL.exe( "Добавить веб-ссылку" в Visual Studio), рассмотрите svcutil.exe вместо этого ( "Добавить ссылку на службу" ).

Если вы используете прокси-сервер WCF, вы можете переопределить данную конфигурацию и разрешить WCF добавлять заголовки для вас:

<security mode="TransportWithMessageCredential">
    <transport clientCredentialType="None" proxyCredentialType="None" realm="" />
    <message clientCredentialType="UserName" algorithmSuite="Default" />
</security>

Оттуда вы можете указать пароль:

RemoteSvcProxy.TheirClient client = new RemoteSvcProxy.TheirClient();
client.ClientCredentials.UserName.UserName = "uname";
client.ClientCredentials.UserName.Password = "pwd";

Я не знаю, каков ваш настраиваемый инструмент, но, возможно, на его основе основаны аналогичные параметры конфигурации.