Невозможно добавить заголовок WS-Security в запрос, созданный из веб-ссылки

Я использовал WebReference, и принимающему серверу требуется заголовок WS-Security:

<wsse:UsernameToken wsu:Id = "Example"> 
    <wsse:Username> ... </wsse:Username>
    <wsse:Password Type = "..."> ... </wsse:Password>
    <wsse:Nonce EncodingType = "..."> ... </wsse:Nonce>
    <wsu:Created> ... </wsu:Created>
</wsse:UsernameToken>

Я предполагал, что это будет включено в WSDL, однако после прочтения эта почта я понял, что логика должна быть разделена.

Класс клиента, который я использую для выполнения запроса, содержит свойство Proxy IWebProxy:HttpWebClientProtocol. Я считаю, что именно здесь я должен предоставить информацию о заголовке/переопределении. Пожалуйста, может кто-нибудь подтвердить это?

У меня также есть код, который, как я знаю, генерирует правильные заголовки. Однако я не уверен, как указать эти заголовки/элементы без изменения файла WebReference.

public static Tuple<EndpointAddress, BindingElementCollection, string, string> PrepareGlowsAuth(string endpoint)
{
    EndpointAddress soapEndpoint = new EndpointAddress(string.Format("{0}/{1}", (IsProduction ? productionBaseUrl : testingBaseUrl), endpoint));
    BasicHttpsBinding binding = new BasicHttpsBinding();
    binding.Security.Mode = BasicHttpsSecurityMode.TransportWithMessageCredential;
    binding.Security.Message.ClientCredentialType = BasicHttpMessageCredentialType.UserName;

    BindingElementCollection elements = binding.CreateBindingElements();
    elements.Find<SecurityBindingElement>().EnableUnsecuredResponse = true;

    return new Tuple<EndpointAddress, BindingElementCollection, string, string>(soapEndpoint, elements, "username", "password");
}

Был бы признателен, если бы кто-то мог указать мне в правильном направлении!

Обновление: после следующего совета я не вижу классы Client или Response.

Невозможно добавить заголовок WS-Security в запрос, созданный из веб-ссылки

Вы видели этот п/о пост? stackoverflow.com/questions/23663007/…

tgolisch 12.06.2019 20:47
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
1
278
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

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

// Assume that you named your "Connected Service" com.example.foo

foo.bar requestObj= new foo.bar();

// Fill in your request object
bar.FirstName = "Someone";
// etc.

// Set up the authentication using the function you provided
var glowsAuthData = PrepareGlowsAuth("expressRateBook");

// foo.<object name>Client is automatically created, this is the generated
//   proxy class for communicating with the intended web service
foo.barClient client = new foo.barClient(new CustomBinding(glowsAuthData.Item2)
                                         , glowsAuthData.Item1);
client.ClientCredentials.UserName.UserName = glowsAuthData.Item3;
client.ClientCredentials.UserName.Password = glowsAuthData.Item4;

// Use the client to send the request object and populate the response object
// foo.<object name>Response is automatically generated when VS generates 
//   the code for "Connected Service". It also makes it the return type 
//   for foo.barClient.barResponse(foo.bar);
foo.barResponse responseObj = client.barResponse(requestObj);

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

Большое спасибо за это. Кажется идеальным. Однако есть одна проблема: я не могу найти класс WebServiceClass в System.Web.Services. Обеспечил ссылку на dll v4

atoms 13.06.2019 15:28

Так что у меня есть WebService requestObj = new System.Web.Services.WebService(); Но ничего для WebServiceClassClient client = new WebServiceClassClient. @Tarek, мне нужно сгенерировать этот класс?

atoms 13.06.2019 15:40

Неудачное название с моей стороны, извините. Тип requestObj должен быть прокси-классом, созданным VS при импорте WSDL. Я назвал свой com.dhl.wsbexpress.expressRateBook. Я пытался сделать его универсальным, но при этом использовал имя, используемое платформой .NET.

Tarek Fadel 13.06.2019 16:48

Спасибо @Tarek. К сожалению, после этого я не вижу классы Client/Reponse, которые должны были быть созданы. Может быть, WSDL или VS неправильно определили классы? (Версия выполнения: 4.0.30319.42000). Добавил изображение, показывающее, что у меня есть.

atoms 13.06.2019 17:32

Также можно подтвердить, что WSDL был сгенерирован из https://wsbexpress.dhl.com/sndpt/expressRateBook?WSDL

atoms 13.06.2019 17:37

А, кажется, я вижу проблему. Когда вы создаете ссылку на службу, вам нужно перейти в раздел «Дополнительно» и выбрать «Всегда создавать контракты сообщений». Я создал пример приложения, которое компилируется и должно сработать. Вы можете скачать его с github.com/tHeCh0s3n0n3/.net-WSSE-пример

Tarek Fadel 13.06.2019 19:56

Большое спасибо Тарек! Я добавлял wsdl как веб-ссылку, а не как ссылку на службу. Очень глупая ошибка!

atoms 13.06.2019 20:58

Другие вопросы по теме