2010-09-08 9 views
7

Ich habe eine Windows-Anwendung geschrieben, um eine Verbindung zu einem Client SAP Web Services zu testen. Der Web-Service-Aufruf erfordert die Sicherheit des X509-Zertifikats.Verbinden mit SAP Web Service von C# .NET-Anwendung

Nach dem Lesen verschiedener Artikel im Internet habe ich drei Möglichkeiten gefunden, um das X509-Zertifikat an den Web-Service-Aufruf anzuhängen. Leider geben alle diese Versuche einen "401 Unauthorized Access" zurück. Ich kann jedoch über die URL in IE eine Verbindung zum Webdienst herstellen.

Hat jemand irgendwelche Behauptungen, was ich falsch machen könnte? Ich bin mit WSE 3.0 und die drei Methoden, die ich um das Zertifikat zu befestigen bin mit lauten wie folgt: -

Zertifikat

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

Token

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

Politik

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

GetSecurityToken() und GetSecuirtyCertificate durchsuchen beide den Zertifikatsspeicher. Die SAPX509Assertion tut dies: -

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

aktualisiert OK, ich habe jetzt einen WCF-Aufruf an Ort und Stelle. Ich konnte die BasicHttpBinding-Methode, die von Eugarps gezeigt wurde, nicht verwenden, da sie sich beschwerte, dass ich eine Verbindung zu einer https-Adresse herstellte und http erwartete ... was einen Sinn ergab. Der Code, den ich jetzt habe, ist: -

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

Es ist noch immer keine Verbindung zum SAP-Web-Service. Der Fehler, den ich erhalte, ist "Die HTTP-Anfrage ist nicht autorisiert mit dem Client-Authentifizierungsschema 'Negotiate'". Ich habe auch versucht mit

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

, die einen ähnlichen Fehler zurückgegeben.

Hat jemand weitere Vorschläge oder Ideen, wo ich falsch liege?

+0

'ZfhhrGbbapiZgeeamsCreateabsResponse' ... Meine Augen ... –

+0

Ich weiß! Nicht die benutzerfreundlichste Namenskonvention. – grimorde

Antwort

-1

Nach all dieser Zeit hat der Kunde endlich jemanden, der sich mit dem Problem von seinem SAP-Ende der Dinge beschäftigen. Stellt sich heraus, dass die WSDL-Dateien, die wir geliefert haben, falsch waren und die Zertifizierung falsch durchgeführt wurde. Ich wiederholte meinen Code mit den neuen WSDL-Dateien und es funktionierte zum ersten Mal.

+0

Dies ist keine Antwort. Sie müssen Ihre Frage entfernen, da sie niemandem hilft. – ataravati

-2

Ist Ihr Zertifikat zufällig einem gültigen Benutzer in Ihrem Benutzerspeicher zugeordnet?

+0

Das Zertifikat wurde von den Jungs am SAP-Ende der Dinge erzeugt, aber ich muss die Antwort als Ja annehmen, wenn das Zertifikat abgeholt und erfolgreich von IE verwendet wird. – grimorde

+0

Bitte fragen Sie in den Kommentaren auf die Frage, keine Fragen als Antwort zu stellen. – Restuta

4

Jetzt kommt das alles aus meiner eigenen Erfahrung, so dass einige davon falsch sein können, aber hier ist, wie ich den Prozess verstehe (ich erhielt keine Dokumentation und meine Firma hatte keine Erfahrung mit dem Aufruf von SAP, bevor ich anfing).

SAP-WS-Aufrufe werden nur von WCF BasicHttpBinding unterstützt, und soweit ich das beurteilen kann, werden nur Klartext-Anmeldeinformationen verwendet. Das bedeutet, dass Sie IPSec oder HTTPS verwenden möchten, wenn Sie Ihre Kommunikation privat machen müssen (außerhalb des Intranets oder vertrauliche Daten im Intranet). Auf unserem SAP-Server ist HTTPS nicht konfiguriert, aber wir verwenden VPN mit IPSec für die externe Kommunikation. Zu beachten ist, dass SAP GUI die Kommunikation standardmäßig auch nicht privat macht. In dieser Situation sind Sie nicht weniger sicher, wenn Sie die unten beschriebene Methode verwenden, als der Business-Anwender in der Halle, der sensible Daten in GUI 7.1 nachschlägt. Hier ist, wie ich zu unserem SAP-Server verbinden intern:

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

Soweit ich in der Lage gewesen, um zu bestimmen, Sicherheit auf Nachrichtenebene wird nicht unterstützt, und Bindungen andere als Basichttpbinding (SOAP 1.1) werden nicht unterstützt.

Wie gesagt, dies ist alles aus Erfahrung und nicht aus dem Training, also wenn jemand etwas durch Kommentare hinzufügen kann, bitte tun Sie dies.

+0

Das Beispiel, das ich gepostet habe, verwendet dynamisch erstellte Bindungen, die ChannelFactory-Caching deaktivieren. Wenn jemand dieses Beispiel in der Produktion verwendet, denken Sie daran. – Sprague

+0

Ich habe den WSE3.0-Prozess verwendet, werde aber das Umschreiben mithilfe von WCF und Ihrem Beispiel oben betrachten. – grimorde

2

Ich habe das gleiche Problem konfrontiert und es scheint, ich habe die Lösung hier gefunden: 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>"; 

Unfortunatelly Ich bin WCF nicht in der Lage in meiner Anwendung zu verwenden, ich habe mit .NET 2.0 und WSE 3.0-Stick, und ich wounder, wenn jemand in der Lage war sollution zu, dass zu finden?

Verwandte Themen