2013-01-14 6 views
6

Ich habe einen WCF-SOAP-Consumer, der von Visual Studio 2012 aus einer WSDL implementiert wird. Die WSDL wurde von PeopleTools generiert. Das Stammobjekt ist vom Typ System.ServiceModel.ClientBase.Mit C# WCF-SOAP-Consumer, der WSSE-Klartextauthentifizierung verwendet?

Ich brauche die SOAP-Anforderung zu ähneln:

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:sch="http://xmlns.oracle.com/Enterprise/Tools/schemas"> 
    <soapenv:Header> 
     <wsse:Security soap:mustUnderstand="1" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"> 
      <wsse:UsernameToken> 
       <wsse:Username>[plain text username goes here]</wsse:Username> 
       <wsse:Password>[plain text password goes here]</wsse:Password> 
      </wsse:UsernameToken> 
     </wsse:Security> 
    </soapenv:Header> 
    <soapenv:Body> 
     <sch:InputParameters> 
      <Last_Name>Aren</Last_Name> 
      <First_Name>Cambre</First_Name> 
     </sch:InputParameters> 
    </soapenv:Body> 
</soapenv:Envelope> 

Hier in der Nähe ist können wir erhalten:

<s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope" xmlns:a="http://www.w3.org/2005/08/addressing"> 
    <s:Header> 
     <a:Action s:mustUnderstand="1">http://schemas.xmlsoap.org/ws/2005/02/trust/RST/Issue</a:Action> 
     <a:MessageID>urn:uuid:3cc3f2ca-c647-466c-b38b-f2423462c837</a:MessageID> 
     <a:ReplyTo> 
      <a:Address>http://www.w3.org/2005/08/addressing/anonymous</a:Address> 
     </a:ReplyTo> 
     <a:To s:mustUnderstand="1">http://[internal URL to soap listener]</a:To> 
    </s:Header> 
    <s:Body> 
     <t:RequestSecurityToken Context="uuid-7db82975-2b22-4236-94a1-b3344a0bf04d-1" xmlns:t="http://schemas.xmlsoap.org/ws/2005/02/trust"> 
      <t:TokenType>http://schemas.xmlsoap.org/ws/2005/02/sc/sct</t:TokenType> 
      <t:RequestType>http://schemas.xmlsoap.org/ws/2005/02/trust/Issue</t:RequestType> 
      <t:KeySize>256</t:KeySize> 
      <t:BinaryExchange ValueType=" http://schemas.xmlsoap.org/ws/2005/02/trust/tlsnego" EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary">FgMBAFoBAABWAwFQ9IhUFGUO6tCH+0baQ0n/3us//MMXzQA78Udm4xFj5gAAGAAvADUABQAKwBPAFMAJwAoAMgA4ABMABAEAABX/AQABAAAKAAYABAAXABgACwACAQA=</t:BinaryExchange> 
     </t:RequestSecurityToken> 
    </s:Body> 
</s:Envelope> 

Sie zwei Probleme auffallen wird:

  • Keine Klartext WSSE Credentials . Übergibt eine binäre Form der Anmeldeinformationen, die der Dienst nicht verwendet.
  • Authentifizierung ist in Body, nicht Header.
  • Die Anfrage unterlässt InputParameters.

Hier ist der wesentliche C# -Code:

var service = new ServiceWithBizarreNameFromPeoplesoft(); 

if (service.ClientCredentials == null) 
    throw new NullReferenceException(); 
service.ClientCredentials.UserName.UserName = "test"; 
service.ClientCredentials.UserName.Password = "password"; 

var binding = new WSHttpBinding(SecurityMode.TransportWithMessageCredential) {Security = new WSHttpSecurity()}; 
service.Endpoint.Binding = binding; 

binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.None; 
binding.Security.Message.ClientCredentialType = MessageCredentialType.UserName; 
binding.Security.Mode = SecurityMode.Message; 

var input = new InputParameters { Last_Name = "Cambre", First_Name = "Aren" }; 

var returnData = service.BizarrePeopleSoftNameForMethod(input); 

Es gibt keine HTTP-Layer-Sicherheit und Transport ist SSL-verschlüsselt. Die Authentifizierung basiert nur auf der SOAP-Nachricht.

+0

Es klingt wie die WSDL schlecht ist. Wenn es in den Tagen von WSE erstellt wurde, ist es wahrscheinlich nicht Standard. –

+0

Interessant. Was lässt Sie denken, dass die WSDL schlecht ist? –

+0

Die Tatsache, dass es einen schlechten Client baut, und die Tatsache, dass es aus den Tagen von WSE zu sein scheint. Es verwendet zum Beispiel SOAP 1.1. –

Antwort

9

Das ist eine Anfrage für das WS-SecureConversation-Token. Es wird standardmäßig von WSHttpSecurity verwendet, es sei denn, Sie ändern seine Eigenschaft EstablishSecurityContext zu false. Verwenden Sie stattdessen diese Bindung:

var binding = new BasicHttpBinding(BasicHttpSecurityMode.TransportWithMessageCredential);  
binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.None; 
binding.Security.Message.ClientCredentialType = BasicHttpMessageCredentialType.UserName; 

Es wird SOAP 1.1 mit UserName-Token verwenden, und es wird HTTPS-Transport erfordern.

Edit:

Zum Testen ohne HTTPS versuchen, diese Gewohnheit zu verwenden Bindung:

var securityElement = SecurityBindingElement.CreateUserNameOverTransportBindingElement(); 
securityElement.AllowInsecureTransport = true; 

var encodingElement = new TextMessageEncodingBindingElement(MessageVersion.Soap11, Encoding.UTF8); 
var transportElement = new HttpTransportBindingElement(); 

var binding = new CustomBinding(securityElement, encodingElement, transportElement); 
+0

Danke. Es sieht so aus, als ob der 'ClientCredentialType' ein' BasicHttpMessageCredentialType' ist, kein 'MessageCredentialType'. Nun ein Problem: Ich benutze vorerst HTTP, um mit Wireshark die Netzwerkverbindung zu schnüffeln. Gibt es eine Möglichkeit, das Verhalten zu überschreiben, HTTPS zu erfordern? Ich habe untersucht, wie man "binding.Security.Mode" ändert, aber es scheint, dass keine der Optionen dies erlauben würde. –

+0

Danke, ich habe das erste Beispiel behoben und eine weitere Option zum Testen ohne HTTPS hinzugefügt. –

+0

Ooh, das ist wirklich nah! Wireshark zeigt, dass die Kommunikation erfolgreich war, aber .NET Framework mag die Antwort nicht: "** Der Sicherheitsprozessor konnte in der Nachricht keinen Sicherheitsheader finden. Dies kann daran liegen, dass die Nachricht ein ungesicherter Fehler ist oder eine Bindung vorliegt Nichtübereinstimmung zwischen den kommunizierenden Parteien Dies kann auftreten, wenn der Dienst für die Sicherheit konfiguriert ist und der Client keine Sicherheit verwendet. ** "Untersuchen der Optionen jetzt ... –

-1

Das sieht für mich wie wsHttpBindings mit Transportsicherheit mit grundlegenden Benutzername Passwort-Authentifizierung.

Diese Zeilen schauen mir falsch:

binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.None; 
binding.Security.Message.ClientCredentialType = MessageCredentialType.UserName; 
binding.Security.Mode = SecurityMode.Message; 

Hier ist, wie ich dies in Ihrer Anwendung oder web.config

<bindings> 
    <wsHttpBinding> 
    <binding name="ws" > 
     <security mode="Transport"> 
     <transport clientCredentialType="Basic" proxyCredentialType="Basic" /> 
     </security> 
    </binding> 
    </wsHttpBinding> 
</bindings> 

<client> 
    <endpoint address="http://www.bla.com/webservice" binding="basicHttpBinding" contract="bla.IService" name="ws" /> 
</client> 

der Code konfiguriert, um zu sehen erwarten würde, dann würde wie folgt aussehen:

var service = new GeneratedProxyClient("basic"); 
service.ClientCredentials.UserName.UserName = "test"; 
service.ClientCredentials.UserName.Password = "password"; 
var input = new InputParameters { Last_Name = "Cambre", First_Name = "Aren" }; 
var returnData = service.BizarrePeopleSoftNameForMethod(input); 

Könnte hier besser erklärt werden ->http://msdn.microsoft.com/en-us/library/ms733775.aspx

+0

Danke, aber nicht mit der Standardauthentifizierung. Die HTTP-Schicht hat keine Authentifizierung. Außerdem bekomme ich einen Fehler, wenn ich '' basic ''als Argument von' var service = new ServiceWithBizarreNameFromPeoplesoft() 'verwende. Wenn Sie eine einzelne Zeichenfolge übergeben, wird erwartet, dass dies der Name eines Endpunktelements ist. Dies scheint von http://msdn.microsoft.com/en-us/library/ms574925.aspx unterstützt zu werden. –

Verwandte Themen