Connect to an SAP web service from a C # .NET application

I wrote a Windows application to test connectivity to SAP web services clients. An X509 certificate certificate is required to call the web service.

After reading various articles on the Internet, I came up with three ways to connect an X509 certificate to a web service call. Unfortunately, all of these attempts return 401 Unauthorized Access. However, I can connect to the web service through the URL in IE.

Does anyone have any opinions on what I can do wrong? I am using WSE 3.0, and the three methods that I use to attach the certificate are as follows: -

Certificate

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

Token

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

Politics

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

GetSecurityToken () and GetSecuirtyCertificate search the certificate store. SAPX509Assertion does the following: -

 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; } 

Update Ok, now I have a WCF call. I could not use the BasicHttpBinding method shown by Eugarps as it complained that I was connecting to the https address and the expected http ... which made sense. The code that I have now is: -

 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); 

I still cannot connect to the SAP web service. The error I get is: "The HTTP request is unauthorized using the Negotiate client authentication scheme. I also tried using

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

which returned a similar error.

Does anyone have any additional suggestions or ideas on where I am going wrong?

+7
c # sap
source share
4 answers

After this time, the client finally got someone to deal with the problem from their end in SAP. It turns out that the WSDL files we supplied were incorrect, and the certification was not performed correctly. I reworked my code with the new WSDL files and it worked for the first time.

-one
source share

Now all this comes from my own experience, so some of them may be wrong, but here is how I understand the process (I did not receive any documentation, and my company did not have experience in calling SAP before I started to do it).

SAP WS calls are only supported by WCF BasicHttpBinding, and as far as I can tell, only plaintext credentials are used. This means that you will want to use IPSec or HTTPS if you need to make your connection private (outside the intranet or confidential data inside the intranet). HTTPS is not configured on our SAP server, but we use a VPN with IPSec for external communication. It is important to note that by default, the SAP GUI also does not make communications private. In this situation, you are no less safe using the method described below than a business user in the room who is looking for important data in the GUI 7.1. Here, as I myself connect to our SAP server:

  //Create binding //Note, this is not secure but it 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; 

To my knowledge, message-level security is not supported, and bindings other than basicHttpBinding (SOAP 1.1) are not supported.

As I said, all this is connected with experience, and not with training, so if someone can add something through comments, do it.

+4
source share

I ran into the same problem and it seems to me that I found a solution: 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>"; 

Unfortunately, I cannot use WCF in my application, I have to stick with .NET 2.0 and WSE 3.0, and I realized if anyone could find a solution for this?

+2
source share

Does your certificate match the correct user in your user repository?

-2
source share

All Articles