2010-10-19 36 views
6

Tình huống: Ứng dụng Silverlight 4 giao tiếp với một thành phần máy chủ thông qua WCF, sử dụng basicHttpBinding và HTTPS.Cách khắc phục sự cố WCF maxClockSkew trong ngữ cảnh ứng dụng HTTPS Silverlight?

Đây là ràng buộc sử dụng phía máy chủ:

<basicHttpBinding> 
<binding name="DefaultSecuredBinding" maxReceivedMessageSize="2147483647" maxBufferSize="2147483647"> 
     <readerQuotas maxDepth="50" maxArrayLength="2147483647" maxStringContentLength="2147483647" /> 
     <security mode="TransportWithMessageCredential"> 
     <message clientCredentialType="UserName"/> 
     <transport clientCredentialType="None" proxyCredentialType="None"/> 
     </security> 
    </binding> 
</basicHttpBinding> 

Chú ý rằng chúng tôi sử dụng TransportWithMessageCredential như chế độ bảo mật. Chứng chỉ được cài đặt đúng trên IIS.

Ứng dụng chạy trơn tru khi chạy cục bộ.

Tuy nhiên, hiện chúng tôi có người dùng bên ngoài kết nối với ứng dụng của chúng tôi. Một số trong số họ đang gặp khó khăn, và nhìn vào bên trong các bản ghi máy chủ, chúng tôi phát hiện ra lỗi này:

"MessageSecurityException" Các timestamp an ninh là cũ vì thời gian hết hạn của nó ('2010-10-18T22: 37: 58.198Z ') là trong quá khứ. Thời gian hiện tại là '2010-10-18T22: 43: 18.850Z' và cho phép đồng hồ nghiêng là '00: 05: 00 '.

Chúng tôi đã thực hiện nghiên cứu thông thường về các chủ đề trên web (StackoverFlow & Google ... và Bing), để đọc thêm về chủ đề. Chúng tôi đã liên hệ với người dùng để đảm bảo rằng họ đã được bù đắp thời gian với máy chủ của chúng tôi, sau này đã được xác nhận.

bài viết MSDN Đây là khởi đầu: http://msdn.microsoft.com/en-us/library/aa738468.aspx

nào sử dụng một CustomBinding trên một ràng buộc hiện có và thiết lập thuộc tính MaxClockSkew trên SecurityBindingElement của ràng buộc tùy chỉnh. Chúng tôi đã triển khai giải pháp này, thay đổi SymmetricSecurityBindingElement thành TransportSecurityBindingElement, vì ràng buộc của chúng tôi cho giao tiếp an toàn với Silverlight là basicHttpBinding với HTTPS.

Một số bài viết trên web (bao gồm bài viết MSDN được liệt kê ở trên) hiển thị đoạn mã bổ sung đặt thuộc tính maxClockSkew thành phần tử khởi động được lấy từ ProtectionTokenParameters. Tôi chưa bao giờ thành công khi áp dụng phần này trong mã của chúng tôi, vì TransportSecurityBindingElement dường như không có bất kỳ ProtectionTokenParameters nào.

Đây là mã của chúng tôi để quấn một ràng buộc với maxClockSkew:

protected virtual System.ServiceModel.Channels.Binding WrapClockSkew(System.ServiceModel.Channels.Binding currentBinding) 
    { 
     // Set the maximum difference in minutes 
     int maxDifference = 300; 

     // Create a custom binding based on an existing binding 
     CustomBinding myCustomBinding = new CustomBinding(currentBinding); 

     // Set the maxClockSkew 
     var security = myCustomBinding.Elements.Find<TransportSecurityBindingElement>(); 
     if (security != null) 
     { 
      security.LocalClientSettings.MaxClockSkew = TimeSpan.FromMinutes(maxDifference); 
      security.LocalServiceSettings.MaxClockSkew = TimeSpan.FromMinutes(maxDifference); 
     } 


     return myCustomBinding; 
    } 

Các 'security.LocalClientSettings' có thể là vô ích ở đây, vì mã này là dành cho phía máy chủ.

Mã này không thực hiện thủ thuật, chúng tôi vẫn có thông báo lỗi tương tự trên máy chủ khi chúng tôi có sự khác biệt lớn hơn 5 phút với máy chủ. Tôi vẫn nhớ rằng chúng tôi đã không áp dụng mẹo khởi động của đoạn mã MSDN .. vì vậy chúng tôi tiếp tục tìm kiếm trên web về chủ đề này.

Chúng tôi đã tìm thấy hành vi wcf gọn gàng mà chúng tôi nghĩ, sẽ khắc phục được sự cố của chúng tôi.

Dường như nó xử lý các vấn đề ràng buộc Bootstrap!

Đây là một phần trong đó nó tìm kiếm thông số Mã trong một bối cảnh của một TransportSecurityBindingElement:

//If the securityBindingElement's type is TransportSecurityBindingElement 
if (securityBindingElement is TransportSecurityBindingElement) 
{ 
foreach (SecurityTokenParameters securityTokenParameters in 
    securityBindingElement.EndpointSupportingTokenParameters.Endorsing) 
{ 
    //Gets it from the EndpointSupportingTokenParameters.Endorsing property 
    if (securityTokenParameters is SecureConversationSecurityTokenParameters) 
    { 
     secureConversationSecurityTokenParameters = 
      securityTokenParameters as SecureConversationSecurityTokenParameters; 

     break; 
    } 
} 
} 

Lưu ý 'securityBindingElement.EndpointSupportingTokenParameters.Endorsing' ... Trong trường hợp của chúng tôi (basicHttpBinding , TransportWithMessageCredential, Https ...), bộ sưu tập này tuy nhiên trống!

Vì vậy, không có cách nào để truy xuất securityTokenParameters, do đó không thể đặt maxClockSkew.

Câu hỏi:

  • Are bindings chúng tôi không chính xác trong một SL + WCF + HTTPS bối cảnh?

  • Có bình thường khi không tìm thấy cách nào để đặt maxClockSkew trên phần tử khởi động trong TransportSecurityBindingElement không?

  • Chúng tôi là công ty duy nhất đang thực hiện ứng dụng HTTPS Silverlight với khách hàng có thể không ở đúng thời điểm chính xác (với + - 5 phút bù đắp)?

  • Tại sao có vẻ như đây là một cuộc phiêu lưu để khắc phục cấu hình tầm thường như vậy?

Mọi trợ giúp sẽ được đánh giá cao!

Trả lời

5

Đoạn mã sau cho phép bạn đặt maxClockSkew trên TransportSecurityBindingElement. Giải pháp của tôi là một Outlook Add-in + WCF hoạt động trong các bối cảnh http và https, vì vậy mặc dù không giống với bối cảnh tương tự như của bạn.

  • Kết buộc của bạn trông chính xác với tôi.
  • Dưới đây là đoạn mã

    WSHttpBinding wsSecureBinding = new WSHttpBinding(SecurityMode.TransportWithMessageCredential, false); 
    wsSecureBinding.Security.Message.ClientCredentialType = MessageCredentialType.UserName; 
    wsSecureBinding.Security.Message.EstablishSecurityContext = true; 
    wsSecureBinding.Security.Message.NegotiateServiceCredential = true; 
    wsSecureBinding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Certificate; 
    wsSecureBinding.ReaderQuotas.MaxStringContentLength = 500000; 
    wsSecureBinding.ReceiveTimeout = 
    wsSecureBinding.SendTimeout = new TimeSpan(0, 5, 0); 
    CustomBinding secureCustomBinding = new CustomBinding(wsSecureBinding); 
    TimeSpan clockSkew = new TimeSpan(0, 15, 0); 
    
    TransportSecurityBindingElement tsecurity = secureCustomBinding.Elements.Find(); 
    SecureConversationSecurityTokenParameters secureTokenParams = (SecureConversationSecurityTokenParameters)tsecurity.EndpointSupportingTokenParameters.Endorsing.OfType().FirstOrDefault(); 
    if (secureTokenParams != null) 
    { 
        SecurityBindingElement bootstrap = secureTokenParams.BootstrapSecurityBindingElement; 
        // Set the MaxClockSkew on the bootstrap element. 
        bootstrap.LocalClientSettings.MaxClockSkew = clockSkew; 
        bootstrap.LocalServiceSettings.MaxClockSkew = clockSkew; 
    }
  • Đồng hồ nghiêng chỉ các vấn đề như bạn đang sử dụng thông tin UserName khách hàng và một số người dùng một trong hai giống như đồng hồ máy tính của họ không phải là thời gian chính xác, hoặc họ không quan tâm

  • Vâng, cấu hình WCF luôn là một cuộc phiêu lưu mà bạn không muốn làm.
+0

Điều đó nghe có vẻ đầy hứa hẹn. Tôi sẽ thử điều này và sẽ cho bạn biết nếu nó khắc phục được sự cố của chúng tôi. Trong khi đó, chúng tôi đã quyết định loại bỏ các thông tin thời gian từ các tin nhắn, vì chúng tôi không cần nó. Nếu không có thông tin thời gian nào được gửi đi, nó sẽ không kiểm tra xác nhận skew đồng hồ. Cảm ơn rất nhiều! –

+0

Tôi nghĩ rằng một vài người sẽ biết ơn nếu bạn có thể cung cấp thông tin về cách xóa thông tin thời gian. Ví dụ. ngay bây giờ tôi có thể hưởng lợi từ nó. :) Cảm ơn trước! – Cornelius

+0

Bạn muốn xóa thông tin thời gian nào? Đồng hồ nghiêng thông tin thời gian? Nếu có thì bạn cần phải chọn một giá trị thay thế cho thuộc tính clientCredentialType vì skew đồng hồ được sử dụng để giữ an toàn cho tên người dùng và mật khẩu. –

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