2008-11-08 33 views
8

Làm thế nào để tôi có thể phân phối chính xác WSDL của một dịch vụ web WCF nằm trong mạng LAN riêng từ phía sau proxy ngược trên IP công cộng?WCF Webservice đằng sau proxy ngược công cộng

Tôi có máy chủ web Apache được định cấu hình ở chế độ proxy ngược để nghe các yêu cầu trên địa chỉ IP công khai và phục vụ chúng từ máy chủ IIS nội bộ. WCF webservice tạo WSDL bằng cách sử dụng địa chỉ FQDN của máy chủ LAN, tất nhiên, không thể được đọc bởi một máy khách dịch vụ web internet.

Có cài đặt nào có thể được định cấu hình trong web.config của ứng dụng wcf hay trong IIS để tùy chỉnh địa chỉ máy chủ lưu trữ được tạo WSDL và đặt địa chỉ công cộng thay thế không?

Trả lời

1

Tôi gặp sự cố tương tự, một trong số đó là độ phân giải của địa chỉ công cộng và địa chỉ máy chủ. Điều này giải quyết vấn đề đó mặc dù tôi vẫn còn có một vài vấn đề xác thực.

http://blogs.msdn.com/wenlong/archive/2007/08/02/how-to-change-hostname-in-wsdl-of-an-iis-hosted-service.aspx

+0

OMG Steve, cảm ơn rất lớn về mối liên kết này, tôi đã phát điên trong vài giờ qua. –

9

Để lớp dịch vụ của bạn thêm thuộc tính:

<ServiceBehavior(AddressFilterMode:=AddressFilterMode.Any)> 

Điều này cho phép các dịch vụ phải được giải quyết bởi các khách hàng như https: // ... nhưng dịch vụ được lưu trữ trên http : // ..... Xem this answer để biết cách tạo tiện ích mở rộng cho phép AddressFilterMode.Any được chỉ định thông qua cấu hình mà không yêu cầu thuộc tính mã.

Trong web.config của máy chủ dịch vụ, phần tử điểm cuối phải có URL tuyệt đối trong thuộc tính địa chỉ là URL công khai sẽ được khách hàng sử dụng. Trong cùng phần tử điểm cuối, đặt thuộc tính listenUri thành URL tuyệt đối mà máy chủ dịch vụ đang nghe. Cách tôi xác định URI tuyệt đối mặc định mà máy chủ đang lắng nghe là thêm một tham chiếu dịch vụ vào một ứng dụng khách mà trỏ máy chủ vật lý nơi dịch vụ được lưu trữ. Web.config của máy khách sẽ có địa chỉ cho dịch vụ. Sau đó tôi sao chép nó vào thuộc tính listenUri trong web.config của máy chủ.

Trong cấu hình hành vi dịch vụ của bạn thêm các yếu tố serviceMetaData với thuộc tính httpGetEnabled = true

Vì vậy, bạn sẽ có một cái gì đó như:

<serviceBehaviors> 
    <behavior name="myBehavior"> 
    <serviceMetadata httpGetEnabled="true" /> 
    </behavior 
</serviceBehaviors> 
... 
<services> 
    <service name="NamespaceQualifiedServiceClass" behavior="myBehavior" > 
    <endpoint address="https://www.sslloadbalancer.com" binding="someBinding" contract="IMyServiceInterface" listenUri="http://www.servicehost.com" ... /> 
    </service> 
</services> 

Tôi không chắc chắn nếu điều này làm việc với an ninh thông, an ninh giao thông . Đối với ứng dụng cụ thể này, các thông tin đăng nhập đã được thông qua như một phần của DataContract, vì vậy chúng tôi đã có chế độ bảo mật basicHttpBinding = none. Vì vận chuyển an toàn (với bộ cân bằng tải ssl) không có vấn đề bảo mật.

Cũng có thể để trống thuộc tính listenUri, tuy nhiên nó phải có mặt. Thật không may, có một lỗi trong WCF nơi địa chỉ cơ sở của các lược đồ được nhập trong WSDL có địa chỉ cơ sở listenUri chứ không phải địa chỉ cơ sở công khai (địa chỉ được cấu hình bằng thuộc tính địa chỉ của điểm cuối). Để giải quyết vấn đề đó, bạn cần phải tạo một triển khai IWsdlExportExtension để đưa trực tiếp các lược đồ đã nhập vào tài liệu WSDL và loại bỏ các nhập khẩu. Một ví dụ về điều này được cung cấp tại đây http://winterdom.com/2006/10/inlinexsdinwsdlwithwcf.Ngoài ra bạn có thể có kế thừa dụ lớp từ BehaviorExtensionElement và hoàn thành hai phương pháp mới với:

Public Overrides ReadOnly Property BehaviorType() As System.Type 
    Get 
     Return GetType(InlineXsdInWsdlBehavior) 
    End Get 
End Property 

Protected Overrides Function CreateBehavior() As Object 
    Return New InlineXsdInWsdlBehavior() 
End Function 

Điều này sẽ cho phép bạn thêm một hành vi mở rộng trong file config và thêm hành vi sử dụng cấu hình thay vì phải tạo một nhà máy dịch vụ.

dưới các yếu tố cấu hình System.ServiceModel thêm:

<endpointBehaviors> 
    <behavior name="SSLLoadBalancerBehavior">   
     <flattenXsdImports/> 
    </behavior> 
    </endpointBehaviors> 
     </behaviors> 
<extensions> 
    <behaviorExtensions> 
    <!--The full assembly name must be specified in the type attribute as of WCF 3.5sp1--> 
    <add name="flattenXsdImports" type="Org.ServiceModel.Description.FlattenXsdImportsEndpointBehavior, Org.ServiceModel, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"/>   
    </behaviorExtensions> 
</extensions> 

Và sau đó tham khảo các hành vi đầu cuối mới trong cấu hình thiết bị đầu cuối của bạn bằng cách sử dụng thuộc tính behaviorConfiguration

<endpoint address="" binding="basicHttpBinding" contract="WCFWsdlFlatten.IService1" behaviorConfiguration="SSLLoadBalancerBehavior"> 
+1

Tôi chỉ muốn lưu ý rằng câu trả lời này dựa trên WCF 3.5. Tôi đã không có cơ hội để kiểm tra xem WCF 4.0 có khắc phục được một số vấn đề này hay không. Tôi biết rằng một số cải tiến đã được thực hiện để hỗ trợ tốt hơn các kịch bản proxy ngược lại. –

+0

Tôi đã thử nó và nó hoạt động, nhưng nó có một vài vấn đề: bạn sẽ phải đặt tất cả các loại, hợp đồng và các ràng buộc trong cùng một không gian tên và nếu bạn có các kiểu có tên FooRequest, bạn sẽ phải đổi tên chúng vì wcf sẽ tạo một kiểu có cùng tên. Đối với tôi, việc thuận tiện hơn để chỉnh sửa các tệp wsdl theo cách thủ công, nếu không, người dùng dịch vụ của tôi sẽ phải thay đổi mã của họ. –

+0

@Dutch - Giải pháp của tôi thường sẽ có một dự án đối tượng kinh doanh và một dự án dịch vụ, mỗi dự án có các không gian tên khác nhau (ví dụ: org.app.bo và org.app.servicemodel). Dữ liệu từ các đối tượng kinh doanh được sao chép vào các đối tượng dịch vụ và ngược lại. Tôi sử dụng các giao diện được định nghĩa trong dự án dịch vụ để xác định các hợp đồng (org.app.servicemodel.ISomeService). Các phương thức dịch vụ thường lấy kiểu org.app.servicemodel.SomethingRequest làm tham số và trả về kiểu org.app.servicemodel.SomethingResponse. Tôi đã không chạy vào các xung đột đặt tên bằng cách sử dụng loại thiết lập này. Bạn có donig cái gì khác? –

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