2011-01-22 10 views
11

Tôi cần tạo một dịch vụ WCF được lưu trữ trong IIS, sử dụng http vận chuyển và giữ trạng thái trong bộ nhớ của máy chủ. Mặc dù tôi biết rằng các dịch vụ nhà nước không phải là một ý tưởng hay, nhưng hạn chế cuối cùng này là cần thiết để làm cho dịch vụ hoạt động với một khách hàng cũ.Phiên WCF với một wsHttpBinding và không có bảo mật cửa sổ

Suy nghĩ đầu tiên của tôi là phiên của asp.net để lưu trữ các giá trị. Tôi kích hoạt chế độ tương thích asp.net trong dịch vụ của mình, điều này đã cho tôi quyền truy cập vào HttpContext, nhưng các giá trị được đặt trong đối tượng phiên không được lưu giữ trong bộ nhớ. Tôi cho rằng điều này là do mô-đun http xử lý trạng thái phiên không được định cấu hình chính xác, nhưng khi googling cho câu trả lời tôi gặp phải, các phiên WCF và nghĩ rằng có thể nên sử dụng chúng. Tuy nhiên, các phiên WCF có vẻ như dưới dạng tài liệu và đặt một bộ điều kiện tiên quyết lạ trên một dịch vụ và tôi không thể tìm thấy cấu hình phù hợp với nhu cầu của mình: phải được lưu trữ trong IIS, phải sử dụng http hoặc https giao thông vận tải và không thể trả lời trên cửa sổ xác thực vì khách hàng và máy chủ sẽ không được một phần của cùng một tên miền. Tôi đang cố gắng để có được điều này bằng cách sử dụng wsHttpBinding, tôi đã nghe các phiên WCF yêu cầu bảo mật hoặc tin nhắn đáng tin cậy, nhưng: - Sử dụng các ràng buộc tiêu chuẩn và khi các máy chủ không phải là một phần của cùng một tên miền nó không thành công với một "SecurityNegotiationException người gọi không được xác thực bởi dịch vụ ”ngoại lệ. Điều này là khá hợp lý vì nó đã được sử dụng bảo mật cửa sổ.

  • Nếu tôi vô hiệu hóa an ninh hoàn thành nó không thành công với một “hợp đồng đòi hỏi phiên, nhưng Binding 'wsHttpBinding' không hỗ trợ nó hoặc không được cấu hình đúng cách để hỗ trợ nó.”

  • Nếu trong khi vẫn giữ an ninh vô hiệu hóa Tôi cho phép tin nhắn đáng tin cậy Tôi nhận được ngoại lệ "Ràng buộc xác nhận không thành công vì WSHttpBinding không hỗ trợ các phiên đáng tin cậy về an ninh giao thông (HTTPS). Không thể mở nhà máy kênh hoặc máy chủ dịch vụ. Sử dụng bảo mật tin nhắn để nhắn tin đáng tin cậy an toàn qua HTTP “.

  • tôi đã cố gắng tạo điều kiện cho mức độ bảo mật vận chuyển nhưng điều này dường như không thực hiện bất kỳ sự khác biệt cho các lỗi phát sinh

Có bất kỳ cấu hình có thể làm việc cho tôi? Hay tôi nên quay lại kế hoạch sử dụng các phiên asp.net?

+0

Tìm thấy phiên asp.net không hoạt động do cookie bị vô hiệu hóa, có phiên bản làm việc của mã sử dụng phiên asp.net. – Robert

Trả lời

25

Bạn có thể có WCF giữ thông tin phiên trong bộ nhớ một cách khá đơn giản. Để loại bỏ mọi ảnh hưởng bên ngoài có thể có trong hướng dẫn của tôi, tôi sẽ giả sử bạn đang bắt đầu với một dự án hoàn toàn mới:

  1. Tạo dự án Thư viện dịch vụ WCF mới. Dự án này đã có một dịch vụ với một cấu hình ràng buộc WSHttpBiding.
  2. Chuyển đến hợp đồng dịch vụ (IService1.cs) và thay đổi thuộc tính ServiceContract như sau:

    [ServiceContract(SessionMode = SessionMode.Required)] 
    
  3. Chuyển đến implimentation dịch vụ (Service1.cs) và thêm dòng sau ServiceBehavior thuộc tính với dịch vụ lớp (Service1):

    [ServiceBehavior(InstanceContextMode = InstanceContextMode.PerSession, ConcurrencyMode = ConcurrencyMode.Single)] 
    
  4. Thêm dữ liệu phiên như các thành viên của lớp dịch vụ (Service1):

    public class Service1 : IService1 
    { 
        ... 
    
        private string UserFullName { get; set; } 
    
        ... 
    } 
    
  5. Sử dụng các thành viên để trình bày dữ liệu phiên cụ thể (nhớ cũng để thêm chúng vào các hợp đồng dịch vụ, IService1):

    public class Service1 : IService1 
    { 
        ... 
    
        public string Welcome(string fullName) 
        { 
         UserFullName = fullName ?? "Guest"; 
         return string.Format("Welcome back, {0}!", UserFullName); 
        } 
    
        public string Goodbye() 
        { 
         return string.Format("Come back soon, {0}!", UserFullName ?? "Guest"); 
        } 
    
        ... 
    } 
    

SessionMode.Required đảm bảo rằng khách hàng của bạn là phiên theo dõi.
InstanceContextMode.PerSession đảm bảo rằng phiên bản của lớp dịch vụ (Service1) được tạo cho mỗi phiên, để bạn có thể giữ lại dữ liệu phiên trong đó và nó sẽ tồn tại trong bộ nhớ trên nhiều cuộc gọi trong cùng một phiên.
ConcurrencyMode.Single đảm bảo chỉ có một chủ đề có thể nhập từng thể hiện của lớp dịch vụ (Service1) và ngăn các vấn đề đồng thời có thể xảy ra nếu bạn chỉ truy cập dữ liệu từ lớp dịch vụ (và vị trí an toàn chủ đề bên ngoài).

CHỈNH SỬA: Theo mặc định, WSHttpBinding chỉ cho phép các phiên bảo mật. Nhưng nó cũng hỗ trợ các phiên đáng tin cậy, cho phép thiết lập phiên mà không cần bảo mật. Cấu hình ràng buộc sau vô hiệu hóa bảo mật và cho phép các phiên đáng tin cậy:

<wsHttpBinding> 
    <binding name="wsHttpBindingConfiguration"> 
     <security mode="None" /> 
     <reliableSession enabled="true" /> 
    </binding> 
</wsHttpBinding> 
+0

Đây là nhiều hơn hoặc ít hơn những gì tôi đã làm, có vẻ như nó cần thông báo cửa sổ cấp xác thực để làm việc. Đây không phải là một tùy chọn cho tôi vì máy khách và máy chủ sẽ không nằm trong cùng một miền. – Robert

+0

@Robert: đúng, nhưng có một giải pháp. Xem chỉnh sửa trên câu trả lời của tôi. Tôi hy vọng điều này sẽ giải quyết vấn đề của bạn. –

+0

Sử dụng cấu hình được đề xuất của bạn trên máy khách, tôi nhận được lỗi sau. ProtocolException: Điểm cuối từ xa đã gửi một lỗi không xác định với không gian tên, http://www.w3.org/2003/05/soap-envelope, tên Người gửi và lý do Không thể xử lý thư. Điều này rất có thể do hành động 'http://schemas.xmlsoap.org/ws/2005/02/rm/CreateSequence' không chính xác hoặc vì thư chứa mã thông báo bảo mật không hợp lệ hoặc hết hạn hoặc do có .. – Robert

1

IMO đây là những gì xảy ra khi bạn đang sử dụng công nghệ có sự trừu tượng kém hơn HTTP như WCF. Thực tế là các dịch vụ web WCF có thể được lưu trữ mà không có HTTP (tức là trên NET TCP, MSMQ, v.v.) chỉ gây khó khăn cho việc sử dụng các tính năng tích hợp của HTTP mà không cần nhập địa chỉ cấu hình và bắt đầu trò chơi "đoán cấu hình đúng bằng cách dùng thử và lỗi "nơi bạn thử mọi hoán vị cấu hình có thể cho đến khi bạn tìm thấy đúng hoán vị hoạt động!

Cuối cùng nếu bạn không thể sử dụng WCF và phải triển khai dịch vụ web từ đầu, bạn chỉ cần đặt cookie khi khách hàng xác thực thành công. Sau đó, với mọi yêu cầu của khách hàng, chỉ cần lấy thông tin phiên được tham chiếu bởi cookie đó.

Một giải pháp khả thi nếu bạn phải sử dụng WCF là quản lý phiên trong tay của bạn (Đó là những gì tôi làm khi tôi không hài lòng với nỗ lực cần thiết để làm việc gì đó) và có một phiên rõ ràng 'tài sản trên tất cả các dịch vụ web của bạn yêu cầu phiên/xác thực (thường là một guid được tạo trên Xác thực). Vì vậy, đối với mỗi yêu cầu tiếp theo, bạn sử dụng guid để bù lại thông tin phiên liên quan đến khách hàng đó.

Nếu bạn quan tâm đến việc thử các khung dịch vụ web khác nhau, tôi duy trì một Open Source Web Services Framework cho phép bạn xây dựng các dịch vụ web không có cấu hình, DRY, có thể kiểm tra (mà không cần bất kỳ cấu hình nào). Các điểm cuối XML, JSON, JSV, SOAP 1.1, SOAP 1.2. Có hiệu quả nó cho phép bạn truy cập vào cùng một dịch vụ web của bạn thông qua một địa chỉ HTTP GET cho các máy khách REST-ful và gỡ lỗi dễ dàng cũng như các điểm cuối SOAP (một lựa chọn phổ biến vẫn được một số doanh nghiệp yêu cầu). Hướng dẫn Hello World sẽ cung cấp cho bạn tổng quan tốt về một số tính năng của nó và cách hoạt động của tính năng này.

+0

Cảm ơn câu trả lời! Trong khi tôi đồng ý phần lớn với câu trả lời của bạn, đó là một hạn chế không may của dự án mà chúng tôi phải sử dụng WCF. Tôi chắc chắn sẽ xem xét ServiceStack cho các dự án có các ràng buộc ít nghiêm ngặt hơn đối với các công nghệ sẽ được sử dụng. – Robert