Подключение к веб-службе SAP из приложения C # .NET - PullRequest
7 голосов
/ 08 сентября 2010

Я написал приложение для Windows, чтобы проверить соединение с клиентскими веб-сервисами SAP. Для вызова веб-службы требуется сертификат X509.

После прочтения различных статей в Интернете я нашел три способа прикрепить сертификат X509 к вызову веб-службы. К сожалению, все эти попытки возвращают «401 Несанкционированный доступ». Однако я могу подключиться к веб-сервису через URL в IE.

У кого-нибудь есть предположения относительно того, что я могу делать неправильно? Я использую WSE 3.0 и три метода, которые я использую для прикрепления сертификата, следующие: -

Сертификат

X509Certificate2 oCert = GetSecurityCertificate(oCertificate);  
svc.ClientCertificates.Add(oCert);

Жетон

X509SecurityToken oToken = GetSecurityToken(oCertificate);
svc.RequestSoapContext.Security.Tokens.Add(oToken);

Политика

SAPX509Assertion sapX509Assertion = new SAPX509Assertion(oCertificate, oStoreLocation, oStoreName, oFindType);  
svc.SetPolicy(sapX509Assertion.Policy());

GetSecurityToken () и GetSecuirtyCertificate выполняют поиск в хранилище сертификатов. SAPX509 Assertion делает это: -

public SAPX509Assertion(String certSubject, StoreLocation oStoreLocation, StoreName oStoreName, X509FindType oFindType)  
{  
    ClientX509TokenProvider = new X509TokenProvider(oStoreLocation,
                                                     oStoreName, certSubject, oFindType);  
    ServiceX509TokenProvider = new X509TokenProvider(oStoreLocation,
                                                     oStoreName, certSubject, oFindType);  

    Protection.Request.EncryptBody = false;  
    Protection.Response.EncryptBody = false;  
} 

Обновление ОК, у меня сейчас звонок на WCF. Я не мог использовать метод BasicHttpBinding, показанный Eugarps, поскольку он жаловался, что я подключался к адресу https и ожидал http ... что имело смысл. У меня сейчас есть код: -

var binding = new WSHttpBinding();
binding.MaxReceivedMessageSize = int.MaxValue;
binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Windows;
binding.Security.Mode = SecurityMode.Transport;

WCFConnection.CreateAbsenceWSlow.ZWSDHTM_GB_AMS_CREATEABS_lowClient client;
CreateAbsenceWSlow.ZfhhrGbbapiZgeeamsCreateabsResponse response;
CreateAbsenceWSlow.ZfhhrGbbapiZgeeamsCreateabs data;
//Assign address
var address = new EndpointAddress(sUrl);

//Create service client
client = new CreateAbsenceWSlow.ZWSDHTM_GB_AMS_CREATEABS_lowClient(binding, address);

//Assign credentials
client.ClientCredentials.UserName.UserName = sUserName;
client.ClientCredentials.UserName.Password = sPassword;

response = new CreateAbsenceWSlow.ZfhhrGbbapiZgeeamsCreateabsResponse();
data = new WCFConnection.CreateAbsenceWSlow.ZfhhrGbbapiZgeeamsCreateabs();

response = client.ZfhhrGbbapiZgeeamsCreateabs(data);

Все еще не удается подключиться к веб-службе SAP. Я получаю сообщение об ошибке: «HTTP-запрос не авторизован по схеме проверки подлинности клиента« Согласование »». Я также пытался использовать

binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Basic;

, который возвратил похожую ошибку.

У кого-нибудь есть какие-либо дополнительные предложения или идеи о том, где я иду не так?

Ответы [ 4 ]

4 голосов
/ 15 сентября 2010

Теперь все это происходит из моего собственного опыта, поэтому некоторые из них могут быть ошибочными, но вот как я понимаю этот процесс (я не получил никакой документации, и у моей компании не было опыта вызова SAP до того, как я начал это делать).

Вызовы SAP WS поддерживаются только WCF BasicHttpBinding, и, насколько я могу судить, только с использованием текстовых учетных данных. Это означает, что вы захотите использовать IPSec или HTTPS, если вам нужно сделать ваше общение частным (вне интрасети или конфиденциальных данных внутри интрасети). На нашем сервере SAP не настроен HTTPS, но мы используем VPN с IPSec для внешней связи. Важно отметить, что по умолчанию графический интерфейс SAP также не делает общение частным. В этой ситуации вы не менее защищены, используя метод, описанный ниже, чем бизнес-пользователь, который просматривает конфиденциальные данные в GUI 7.1. Вот как я подключаюсь к нашему серверу SAP внутри:

        //Create binding
        //Note, this is not secure but it's not up to us to decide. This should only ever be run within
        //the VPN or Intranet where IPSec is active. If SAP is ever directly from outside the network,
        //credentials and messages will not be private.
        var binding = new BasicHttpBinding();
        binding.MaxReceivedMessageSize = int.MaxValue;
        binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Basic;
        binding.Security.Mode = BasicHttpSecurityMode.TransportCredentialOnly;

        //Assign address
        var address = new EndpointAddress(Host);

        //Create service client
        var client = new SAP_RFC_READ_TABLE.RFC_READ_TABLEPortTypeClient(binding, address);

        //Assign credentials
        client.ClientCredentials.UserName.UserName = User;
        client.ClientCredentials.UserName.Password = Password;

Насколько мне удалось определить, безопасность на уровне сообщений не поддерживается, а привязки, кроме basicHttpBinding (SOAP 1.1), не поддерживаются.

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

2 голосов
/ 19 января 2011

Я столкнулся с той же проблемой, и, кажется, я нашел решение здесь: http://ddkonline.blogspot.com/2009/08/calling-sap-pi-web-service-using-wcf.html.

        CustomBinding binding = new CustomBinding();
        binding.Elements.Add(new TextMessageEncodingBindingElement(MessageVersion.Soap11, Encoding.UTF8));
        HttpsTransportBindingElement transport = new HttpsTransportBindingElement();
        transport.AuthenticationScheme = AuthenticationSchemes.Basic;
        //transport.ProxyAuthenticationScheme = AuthenticationSchemes.Basic;
        transport.Realm = "XISOAPApps";
        binding.Elements.Add(transport);
        var address = new EndpointAddress("https://foooo");
        ........ create client proxy class


        service.ClientCredentials.UserName.UserName = "<login>";
        service.ClientCredentials.UserName.Password = "<password>";

К сожалению, я не могу использовать WCF в своем приложении, я должен придерживатьсяс .NET 2.0 и WSE 3.0, и я был бы рад, если кто-нибудь смог найти решение этой проблемы?

0 голосов
/ 28 марта 2011

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

0 голосов
/ 08 сентября 2010

Действительно ли ваш сертификат сопоставлен с действительным пользователем в вашем пользовательском магазине?

...