Подключение к веб-службе SAP из C#.NET применение
Я написал приложение Windows для тестирования подключения к веб-службам SAP клиентов. Вызов веб-службы требует безопасности сертификата X509.
после прочтения различных статей в Интернете я придумал три способа прикрепить сертификат X509 к вызову веб-службы. К сожалению, все эти попытки возвращают "401 несанкционированный доступ". Однако я могу подключиться к веб-службе через URL-адрес в IE.
есть ли у кого-нибудь какие-либо sugestions относительно что я делаю не так? Я использую 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 оба поиска в хранилище сертификатов. SAPX509Assertion делает это: -
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-запрос неавторизован со схемой аутентификации клиента "Negotiate"". Я также пробовал использовать
binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Basic;
который вернул аналогичную ошибку.
есть ли у кого-нибудь еще предложения или идеи о том, куда я иду не так?
4 ответов
теперь все это исходит из моего собственного опыта, поэтому некоторые из них могут быть неправильными, но вот как я понимаю процесс (я не получил никакой документации, и у моей компании не было опыта вызова SAP, прежде чем я начал это делать).
вызовы SAP WS поддерживаются только WCF BasicHttpBinding и, насколько я могу судить, только с использованием учетных данных обычного текста. Это означает, что вы захотите использовать IPSec или HTTPS, если вам нужно сделать вашу связь частной (вне интрасети или конфиденциальных данных в интранете). Наш сервер SAP не имеет настроенного HTTPS, но мы используем VPN с IPSec для внешней связи. Важно отметить, что по умолчанию SAP GUI также не делает связь частной. В этой ситуации вы не менее безопасны, используя метод, описанный ниже, чем бизнес-пользователь, который ищет конфиденциальные данные в 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), не поддерживаются.
Как я уже сказал, Это все из опыта, а не из обучения, поэтому, если кто-то может добавить что-то через комментарии, пожалуйста, сделайте это.
я столкнулся с той же проблемой, и, похоже, я нашел решение здесь: 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, и я wounder, если кто-нибудь смог найти решение для этого?
после всего этого времени, клиент, наконец, получил кого-то, чтобы справиться с проблемой из их сок конечных вещей. Оказывается, файлы WSDL, которые мы предоставили, были неправильными, и сертификация была сделана неправильно. Я повторил свой код с новыми файлами WSDL, и он работал в первый раз.