2013-01-14 36 views
6

Tôi có một người dùng WCF SOAP được triển khai bởi Visual Studio 2012 từ WSDL. WSDL được tạo bởi PeopleTools. Đối tượng cơ sở là loại System.ServiceModel.ClientBase.Với C#, WCF SOAP người tiêu dùng sử dụng xác thực văn bản thuần túy WSSE?

tôi cần yêu cầu SOAP giống:

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

Dưới đây là gần nhất chúng ta có thể nhận được:

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

Bạn sẽ nhận thấy hai vấn đề:

  • Không credentials WSSE rõ . Vượt qua dạng nhị phân của thông tin đăng nhập mà dịch vụ sẽ không sử dụng.
  • Xác thực nằm trong Body, không phải Header.
  • Yêu cầu bỏ qua InputParameters.

Dưới đây là đoạn code cần thiết C#:

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

Không có an ninh lớp HTTP, và vận chuyển là được mã hóa SSL. Xác thực chỉ dựa trên thông điệp SOAP.

+0

Nghe có vẻ như WSDL là xấu. Nếu nó được tạo ra trong những ngày của WSE, thì nó có thể không chuẩn. –

+0

Thú vị. Điều gì khiến bạn nghĩ WSDL là xấu? –

+0

Thực tế là nó xây dựng một khách hàng xấu, và thực tế là nó xuất hiện từ những ngày của WSE. Ví dụ, nó sử dụng SOAP 1.1. –

Trả lời

9

Đó là yêu cầu mã thông báo WS-SecureConversation. Nó được sử dụng bởi WSHttpSecurity theo mặc định trừ khi bạn thay đổi thuộc tính EstablishSecurityContext thành false. Thay vào đó, hãy sử dụng liên kết này:

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

Nó sẽ sử dụng mã SOAP 1.1 với tên người dùng và nó sẽ yêu cầu vận chuyển HTTPS.

Edit:

Để thử nghiệm mà không HTTPS cố gắng sử dụng ràng buộc tùy chỉnh này:

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

Cảm ơn. Có vẻ như 'ClientCredentialType' phải là một' BasicHttpMessageCredentialType', không phải là 'MessageCredentialType'. Bây giờ một vấn đề: Tôi đang sử dụng HTTP cho bây giờ để tôi có thể sniff các conneciton mạng bằng cách sử dụng Wireshark. Có cách nào để ghi đè hành vi yêu cầu HTTPS không? Tôi đã điều tra việc thay đổi 'binding.Security.Mode', nhưng dường như không có tùy chọn nào cho phép điều này. –

+0

Cảm ơn, tôi đã sửa ví dụ đầu tiên và thêm một tùy chọn khác để thử nghiệm mà không cần HTTPS. –

+0

Ooh, điều này thực sự gần gũi! Wireshark cho thấy giao tiếp thành công, nhưng .NET Framework không thích phản hồi: "** Bộ xử lý bảo mật không thể tìm thấy tiêu đề bảo mật trong thư. Điều này có thể do thư là lỗi không an toàn hoặc do có một ràng buộc Điều này có thể xảy ra nếu dịch vụ được cấu hình để bảo mật và máy khách không sử dụng bảo mật. ** "Điều tra các tùy chọn ngay bây giờ ... –

-1

Điều này trông giống như tôi wsHttpBindings với bảo mật Giao thông bằng cách sử dụng xác thực mật khẩu tên người dùng cơ bản.

Những dòng này nhìn sai với tôi:

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

Đây là cách tôi mong chờ để thấy điều này cấu hình trong ứng dụng hoặc 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> 

của bạn Sau đó mã sẽ trông như thế này:

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

Có thể giải thích rõ hơn tại đây ->http://msdn.microsoft.com/en-us/library/ms733775.aspx

+0

Cảm ơn nhưng không sử dụng xác thực cơ bản. Lớp HTTP không có xác thực. Ngoài ra, tôi gặp lỗi khi sử dụng '" basic "' làm đối số của 'var service = new ServiceWithBizarreNameFromPeoplesoft()'. Rõ ràng, nếu bạn vượt qua một chuỗi, nó hy vọng rằng sẽ là tên của một phần tử điểm cuối. Điều đó dường như được hỗ trợ bởi http://msdn.microsoft.com/en-us/library/ms574925.aspx. –

Các vấn đề liên quan