2012-03-28 21 views
5

Tôi đang viết một máy khách WCF sử dụng dịch vụ web không phải của.Net, sử dụng WS-Security. Phản hồi của dịch vụ chứa tiêu đề Bảo mật với hàm mustUnderstand được đặt thành true.WCF Client - Cách xử lý hoặc bỏ qua phần tử tiêu đề MustUnderstand?

Sử dụng ServiceModelListener, tôi thấy dữ liệu thực tế quay trở lại từ dịch vụ. Tuy nhiên, WCF client không thành công vì nó không xử lý tiêu đề Security.

<env:Header> 
<wsse:Security env:mustUnderstand="1" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"> 
<wsu:Timestamp wsu:Id="timestamp"> 
<wsu:Created>2012-03-28T13:43:54.474Z</wsu:Created> 
<wsu:Expires>2012-03-28T13:48:54.474Z</wsu:Expires> 
</wsu:Timestamp> 
</wsse:Security> 
</env:Header> 

WCF Lỗi Khách hàng nhắn:

Tiêu đề 'Bảo mật' từ không gian tên 'http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd' đã không được hiểu bởi người nhận thông điệp này, gây ra thông điệp tới không được xử lý. Lỗi này thường chỉ ra rằng người gửi thư này đã kích hoạt giao thức truyền thông mà người nhận không thể xử lý. Hãy đảm bảo rằng cấu hình ràng buộc của máy khách phù hợp với ràng buộc của dịch vụ.

Máy khách WCF của tôi không cần bất kỳ thông tin nào về dấu thời gian. Có một cách dễ dàng để khai thác trong một thói quen xử lý? Tôi đã thử mở rộng lớp Phản hồi & thêm thuộc tính [MessageHeader].

EDIT:

Khi được hỏi một cách khác: Làm thế nào để thực hiện một khách hàng WCF chấp nhận yếu tố tiêu đề tùy chỉnh được đánh dấu Phải Hiểu?

Trả lời

1

Có các tiêu chuẩn khác nhau về WS-Security. Có thể có ý nghĩa khi thay đổi ràng buộc ở phía máy khách, vì basicHttpBinding và wsHttpBindings đang làm việc với các tiêu chuẩn bảo mật khác nhau.

+1

Cảm ơn, nhưng dịch vụ chỉ hỗ trợ basicHttpBinding. –

2

Tôi gặp sự cố tương tự. Tôi không chắc liệu điều này có hữu ích hay không.

MSDN WCF Khả năng mở rộng

http://blogs.msdn.com/b/carlosfigueira/archive/2011/04/19/wcf-extensibility-message-inspectors.aspx

Các thiết lập ở đây là dựa trên chứng chỉ, Oracle Application Server 10g, và Net để tiêu thụ các dịch vụ. Sử dụng SOAPUi rất hữu ích trong khi cố gắng tìm ra những gì đã xảy ra với Yêu cầu và sau đó là phản hồi.

Tôi chưa thử sửa đổi mã để sử dụng basicHttpBinding, nhưng tôi đã sử dụng WSHttpBinding làm cơ sở cấu hình của tôi trong mã. Sau đó, sử dụng

WSHttpBinding binding = new WSHttpBinding() 
     { 
      CloseTimeout = new TimeSpan(0, 1, 0), 
      OpenTimeout = new TimeSpan(0, 1, 0), 
      SendTimeout = new TimeSpan(0, 1, 0), 
      AllowCookies = false, 
      BypassProxyOnLocal = false, 
      HostNameComparisonMode = HostNameComparisonMode.StrongWildcard, 
      MaxBufferPoolSize = 524288, 
      MaxReceivedMessageSize = 65536, 
      MessageEncoding = WSMessageEncoding.Text, 
      UseDefaultWebProxy = false, 
      ReaderQuotas = new System.Xml.XmlDictionaryReaderQuotas() 
      { 
       MaxDepth = 32, 
       MaxArrayLength = 16384, 
       MaxBytesPerRead = 4096, 
       MaxNameTableCharCount = 16384, 
       MaxStringContentLength = 8192 
      } 
     }; 
     binding.Security.Mode = SecurityMode.Transport; 
     binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Certificate; 
     binding.Security.Transport.ProxyCredentialType = HttpProxyCredentialType.None; 
     binding.Security.Transport.Realm = string.Empty; 
     binding.Security.Message.ClientCredentialType = MessageCredentialType.Certificate; 
     binding.Security.Message.EstablishSecurityContext = true; 
     binding.Security.Message.NegotiateServiceCredential = true; 

     CustomBinding customBinding = new CustomBinding(); 
     BindingElementCollection collection = binding.CreateBindingElements(); 

Lặp lại cho TextMessageEncodingBindingElement để đặt Soap11 và AddressingVersion to None.

foreach (BindingElement element in collection) 
     { 
      if (typeof(TextMessageEncodingBindingElement) == element.GetType()) 
      { 
       TextMessageEncodingBindingElement item = element as TextMessageEncodingBindingElement; 
       if (null != item) 
       { 
        item.MessageVersion = MessageVersion.CreateVersion(EnvelopeVersion.Soap11, AddressingVersion.None); 
        customBinding.Elements.Add(item); 
       } 
      } 
      else 
       customBinding.Elements.Add(element); 
     } 

Tôi đã sử dụng ChannelFactory và thêm Hành vi EndPoint cho Trình kiểm tra thư. Tại thời điểm này, tôi đã kiểm soát yêu cầu và tôi có thể thêm tiêu đề thích hợp và sửa đổi mustUnderstand trên Hành động.

Sử dụng SOAPUi Tôi đã nhắn tin.ToString() và đặt nó vào SOAPUI và kiểm tra yêu cầu.Khi các mục cần thiết đã được thêm vào yêu cầu, sau đó nó được xác định rằng máy chủ OAS không trả lời tất cả các phần tử cần thiết. Sử dụng trình kiểm tra thư cho thư trả lời, tôi đã sửa đổi thư để bao gồm các tiêu đề bị thiếu. Tôi không thể nhớ nơi tôi đã tìm thấy mã cơ sở cho trình kiểm tra thư nhưng bạn cần phải sửa đổi mã của mình để sử dụng mã đó một cách chính xác.

Ví dụ của tôi ở đây là một số đoạn trích.

Đối với thông điệp chuyển trong

public object BeforeSendRequest 

tôi cần phải sửa đổi Header, vì vậy sử dụng một vòng lặp for tôi nắm lấy XElement và thêm tiêu đề OASIS và thêm một To.

XNamespace xmlns = "http://schemas.xmlsoap.org/soap/envelope/"; 
       XElement securityHeader = new XElement(
        xmlns + "Security", 
        new XAttribute(xmlns + "wsse", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"), 
        new XAttribute(xmlns + "xmlns", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"), 
        new XAttribute(xmlns + "mustUnderstand", "0")); 
       element.Add(securityHeader); 

Tôi cũng đã phải thay đổi hành động Tiêu đề

else if (localName.Equals("Action", StringComparison.InvariantCultureIgnoreCase)) 
      { 
       foreach (XAttribute a in element.Attributes()) 
       { 
        if (a.Name.LocalName == "mustUnderstand") 
         a.Value = "0"; 
       } 
      } 

Vấn đề của tôi là Dịch vụ không trả lời với một hành động Tiêu đề

Vì vậy, trong

public void AfterReceiveReply 

Tôi gọi là ReturnReply của tôi trở về loại tin nhắn với một cái gì đó như sau. Bạn có thể cần phải sửa đổi các giá trị cho chuỗi.Empty, nhưng đây chỉ là một ví dụ.

...

Message reply = Message.CreateMessage(message.Version, null, reader); 
     reply.Headers.Add(MessageHeader.CreateHeader("Action", string.Empty, string.Empty, false)); 
     reply.Properties.CopyProperties(message.Properties); 

...

tôi thực sự sẽ đề nghị sử dụng một công cụ như SOUPUI để beable để gây rối với phong bì và xem câu trả lời. Nếu bạn thực hiện SSL, bạn sẽ cần tạo một tệp cacert và đặt nó trong SSLSettings của các tùy chọn.

+0

Cảm ơn Adam! trông giống như thông tin thú vị. Tuy nhiên, tôi đã chuyển sang một cam kết tham vấn khác, vì vậy không còn có thể thử những thứ khác với hệ thống đó. Fyi, trước đây khách hàng cuối cùng đã giải quyết vấn đề thông qua một cách tiếp cận kiến ​​trúc khác nhau. –

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