Не знаю, как создать заголовок SOAP <wsse: Security> - PullRequest
10 голосов
/ 09 апреля 2009

У меня практически нет опыта работы с протоколом SOAP. Сервис мне нужно подключить к нужному заголовку. Я думаю, что это несколько стандартно в Java, но в C # этот заголовок нужно создавать вручную.

Кто-нибудь здесь смог подключиться к аналогичному сервису: создал заголовок или, может быть, даже знает о какой-то стандартной библиотеке, которая упростит создание заголовка? Можете поделиться кодом или ссылками?

Я также нашел подсказку, что, возможно, заголовок будет сгенерирован при использовании WS2005, потому что для него есть надстройка WS3. Кто-нибудь может это прокомментировать? После быстрого просмотра этого надстройки я обнаружил одинаковые поля, как в заголовке Security, но все еще не смог создать заголовок.

Ответы [ 5 ]

12 голосов
/ 05 января 2012

Мы смогли решить эту проблему с помощью следующего кода:

public class SecurityHeader : System.ServiceModel.Channels.MessageHeader {
    public string userName;
    public string password;

    protected override void OnWriteStartHeader (System.Xml.XmlDictionaryWriter writer, System.ServiceModel.Channels.MessageVersion messageVersion)
    {
        writer.WriteStartElement("wsse", Name, Namespace);
        writer.WriteXmlnsAttribute("wsse", Namespace);
    }

    protected override void OnWriteHeaderContents (System.Xml.XmlDictionaryWriter writer, System.ServiceModel.Channels.MessageVersion messageVersion)
    {
        writer.WriteStartElement("wsse", "UsernameToken", Namespace);

        writer.WriteStartElement("wsse", "Username", Namespace);
        writer.WriteValue(userName);
        writer.WriteEndElement();

        writer.WriteStartElement("wsse", "Password", Namespace);
        writer.WriteValue(password);
        writer.WriteEndElement();

        writer.WriteEndElement();

    }

    public override string Name
    {
        get { return "Security"; }
    }

    public override string Namespace
    {
        get { return "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"; }
    }
}

Написал заголовок, который требовался для поля DataPower.

Как использовать класс SecurityHeader

    public static void Main(string[] args)
    {

        var webService = new ServiceReference1.MyWebService();
        ....
       webService.Open();


        using (OperationContextScope scope = new OperationContextScope((IContextChannel)webService.InnerChannel))
        {

            var myObjRequest = GetMyObjRequest();

            MessageHeaders messageHeadersElement = OperationContext.Current.OutgoingMessageHeaders;
            messageHeadersElement.Add(SecurityHeader("UserName", "Password"))


             var res = webService.MyServe(myObjRequest);
            Console.WriteLine(res.ToString());
        }
    }
6 голосов
/ 09 апреля 2009

Забавно, вы должны упомянуть об этом - я делал точно , что недавно.

Мне удалось сделать это, используя SoapExtension, который использует ChainStream, чтобы сохранить копию исходного потока, просто копирует поток во время BeforeDeserialize и добавляет заголовок во время AfterSerialize.

Добавление заголовка - это случай чтения содержимого «нового» потока (возвращаемого из ChainStream) в документ XML (XDocument в моем случае), добавления заголовка и последующей записи его в исходный файл. поток перешел в ChainStream.

К сожалению, это довольно грязно, и вы не можете (насколько мне известно) использовать новый экземпляр с соответствующей информацией для аутентификации, когда вам нужно.

У меня в большинстве случаев используется взамен SoapHeader, добавление соответствующего атрибута для каждого метода веб-службы, а также соответствующего поля / свойства с экземпляром требуемого заголовка - но сериализация SOAP в настоящее время доставляет мне головную боль с точки зрения определения правильных имен элементов (с пространствами имен). Это то, о чем я планировал спросить других, когда у меня будет время.

Извините, что не могу дать вам полный ответ - а также извинения за отсутствие кода, он принадлежит компании, а не мне - но, надеюсь, это по крайней мере даст вам отправную точку.

5 голосов
/ 09 апреля 2009

обычно очень легко добавить SOAP-заголовок к вашему веб-прокси-серверу в .Net. Вот быстрый пример кода.

Создать новый заголовок SOAP

using System.Web.Services.Protocols;

public class SoapAuthHeader : SoapHeader
{
public string Username;
public string Password;
}

В прокси-классе вашего веб-сервиса:

public class MyWebServicesProxy : System.Web.Services.Protocols.SoapHttpClientProtocol {

    public SoapAuthHeader AuthHeader;

    ...

}

А затем использовать:

SoapAuthHeader authHeader = new SoapAuthHeader();
authHeader.Username = "username";
authHeader.Password = "password";

MyWebServicesProxy myProxy = new MyWebServicesProxy();
myProxy.AuthHeader = authHeader;

Редактировать: есть и другие способы, и у Microsoft есть библиотека WSE , которая включает WS-Security, что дает гораздо больше функциональных возможностей, чем простой пример выше. Если вам нужны токены Kerberos или подпись сертификата в заголовке SOAP, тогда это путь. если вам просто необходимо добавить простое имя пользователя и пароль для веб-службы, работающей по протоколу SSL, тогда может понадобиться только пример.

Редактировать: Быстрая реклама WSE В начале этого десятилетия, когда веб-сервисы собирались захватить мир, группа отраслевых игроков (Microsoft, IBM, Sun и т. Д.) Собрались вместе, чтобы придумать стандартные способы. делать вещи над ними. Сформированное тело было ОАЗИС . С тех пор Microsoft выпустила несколько версий своей библиотеки WSE для поддержки некоторых спецификаций, но, что интересно, они никогда не были включены в .Net Framework, хотя первая версия была опубликована в 2003 году.

Веб-сервисы все еще очень популярны, и, на мой взгляд, отличный способ интеграции между различными интернет-приложениями немного потерял популярность. Одна из причин, несомненно, заключается в том, что AJAX и веб-сервисы не были лучшими помощниками, хотя и улучшились. Веб-сервисы также становятся довольно сложными, как только вы начинаете включать все дополнительные спецификации sWSE, и одной из вещей, которые должны были быть решены веб-сервисами, была сложность в других протоколах RPC, CORBA и т. Д. Тем временем REST приобрел большую популярность за счет веб-сервисов и библиотек AJAX часто предпочитают его.

Веб-сервисы не собираются исчезать в ближайшее время любыми средствами, но они, вероятно, также не собираются захватывать Мир в ближайшее время.

1 голос
/ 22 октября 2009

Существует настраиваемая привязка с открытым исходным кодом, называемая ClearUserNameBinding, эта привязка помогает передавать UserNameToken как clearText по Http. Это помогло мне, когда веб-сервис на основе Java нужно было использовать с использованием WCF.

http://code.google.com/p/wcf-clear-username-binding/ http://webservices20.blogspot.com/2008/11/introducing-wcf-clearusernamebinding.html

0 голосов
/ 11 марта 2019

Решение от Доменико Зинзи работало для меня со следующими изменениями: Я создал конструктор в классе SecurityHeader:

public SecurityHeader(string userName, string password){ userName = userName; password = password; }

и при вызове я использовал ключевое слово "New", как указано ниже:

messageHeadersElement.Add(New SecurityHeader("UserName", "Password"))

И это сработало:)

P.S. Невозможно добавить это в качестве комментариев, поэтому добавим его сюда.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...