Search code examples
c#.netc#-3.0

Connecting to SAP Web Service from C# .NET application


I've written a Windows Application to test a connection to a clients SAP web services. The web service call requires X509 certificate security.

After reading various articles on the internet I've come up with three ways to attach the X509 certificate to the web service call. Unfortunately all of these attempts return this error:

401 Unauthorised Access

However, I can connect to the web service via the URL in IE.

Does anybody have any suggestions as to what I may be doing wrong? I am using WSE 3.0 and the three methods I am using 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);

Policy

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

GetSecurityToken() and GetSecuirtyCertificate both search the certificate store. The SAPX509Assertion does this:-

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, I have a WCF call now in place. I couldn't use the BasicHttpBinding method shown by Eugarps as it complained that I was connecting to a https address and expected http...which made sense. The code I now have 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);

It's still failing to connect to the SAP web service. The error I am receiving is:

The HTTP request is unauthorized with client authentication scheme 'Negotiate'

I've also tried using

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

which returned a similar error.

Does anybody have any further suggestions or ideas of where I am going wrong?


Solution

  • After all this time, the client has finally obtained someone to deal with the issue from their SAP end of things. Turns out the WSDL files we were supplied were incorrect and the certification had been done wrong. I reran my code with the new WSDL files and it worked first time.