2010-09-08 13 views
7

Ho scritto un'applicazione Windows per verificare una connessione ai servizi Web SAP di un cliente. La chiamata al servizio web richiede la sicurezza del certificato X509.Connessione al servizio Web SAP dall'applicazione C# .NET

Dopo aver letto vari articoli su Internet, ho trovato tre modi per collegare il certificato X509 alla chiamata al servizio web. Sfortunatamente tutti questi tentativi restituiscono un 'accesso non autorizzato' 401. Tuttavia, posso collegarmi al servizio web tramite l'URL in IE.

Qualcuno ha qualche suggerimento su cosa potrei fare di sbagliato? Sto usando WSE 3.0 e tre metodi che sto usando per collegare il certificato sono i seguenti: -

Certificato

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

Token

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

politica

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

GetSecurityToken() e GetSecuirtyCertificate eseguono entrambe la ricerca nell'archivio certificati. Il SAPX509Assertion fa questo: -

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

Aggiornamento OK, ho una chiamata WCF ora in atto. Non ho potuto utilizzare il metodo BasicHttpBinding mostrato da Eugarps in quanto lamentava il fatto che mi stavo connettendo a un indirizzo https e mi aspettavo http ... che avesse senso. Il codice che ora ho è: -

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

Non riesce ancora a connettersi al servizio Web SAP. L'errore che sto ricevendo è "La richiesta HTTP non è autorizzata con lo schema di autenticazione del client 'Negoziare'". Ho anche provato a utilizzare

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

che ha restituito un errore simile.

Qualcuno ha ulteriori suggerimenti o idee su dove sto andando male?

+0

'ZfhhrGbbapiZgeeamsCreateabsResponse' ... I miei occhi ... –

+0

Lo so! Non è il più facile da usare delle convenzioni di denominazione. – grimorde

risposta

-1

Dopo tutto questo tempo, il client ha finalmente ottenuto qualcuno per gestire il problema dalla sua fine SAP. Risulta che i file WSDL che ci sono stati forniti erano errati e che la certificazione era stata effettuata in modo errato. Riesero il mio codice con i nuovi file WSDL e ha funzionato la prima volta.

+0

Questa non è una risposta. Devi rimuovere la tua domanda, in quanto non aiuta nessuno. – ataravati

-2

Il tuo certificato è stato mappato a un utente valido nel tuo negozio utente?

+0

Il certificato è stato generato dai ragazzi alla fine delle cose SAP, ma devo assumere la risposta come sì se il certificato viene prelevato e utilizzato con successo da IE. – grimorde

+0

Si prega di chiedere in commenti alla domanda, non inviare domande in risposta. – Restuta

4

Ora, tutto questo deriva dalla mia esperienza, quindi alcuni di essi potrebbero essere errati, ma ecco come ho capito il processo (non ho ricevuto documentazione e la mia azienda non aveva esperienza nel chiamare SAP prima di iniziare a farlo).

Le chiamate SAP WS sono supportate solo da WCF BasicHttpBinding e, per quanto posso dire, solo utilizzando credenziali di solo testo. Ciò significa che si desidera utilizzare IPSec o HTTPS se è necessario rendere la comunicazione privata (all'esterno della intranet o dati sensibili all'interno della rete Intranet). Il nostro server SAP non ha configurato HTTPS, ma usiamo VPN con IPSec per le comunicazioni esterne. È importante notare che, per impostazione predefinita, la GUI SAP non rende la comunicazione privata. In questa situazione, non sei meno sicuro utilizzando il metodo descritto di seguito rispetto all'utente business in fondo alla ricerca di dati sensibili nella GUI 7.1. Ecco come mi collego al nostro server SAP internamente:

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

Per quanto sono stato in grado di determinare, la sicurezza a livello di messaggio non è supportato, e attacchi diversi da quelli basicHttpBinding (SOAP 1.1) non sono supportati.

Come ho detto, tutto deriva dall'esperienza e non dall'allenamento, quindi se qualcuno può aggiungere qualcosa attraverso i commenti, si prega di farlo.

+0

Inoltre, l'esempio che ho pubblicato utilizza associazioni create dinamicamente che disabiliteranno la memorizzazione nella cache di ChannelFactory. Se qualcuno utilizza questo esempio in produzione, tienilo a mente. – Sprague

+0

Stavo usando il processo WSE3.0 ma guarderò la riscrittura usando WCF e il tuo esempio sopra. – grimorde

2

Ho affrontato lo stesso problema e sembra che ho trovato il sollution qui: 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>"; 

Purtroppo io non sono in grado di utilizzare WCF nella mia richiesta, devo attaccare con .NET 2.0 e WSE 3.0, ed io feritore se qualcuno è stato in grado di trovare sollution a questo?

Problemi correlati