2010-10-31 55 views
5

Tôi có một trình bổ sung Internet Explorer, được viết bằng C#, nói qua WCF có tên là ống dẫn đến ứng dụng .NET trên máy tính. Ứng dụng máy tính để bàn tạo ServiceHost cho netNamedPipeBinding và mỗi cá thể của trình bổ sung IE tạo ChannelFactory để nói chuyện với ứng dụng. Mọi thứ hoạt động tốt dưới Windows XP, nhưng ngoại lệ được ném theo chế độ được bảo vệ của IE trong Windows 7.Làm thế nào để giảm tính toàn vẹn của WCF được đặt tên theo đường ống

System.ServiceModel.CommunicationException: Không thể kết nối với điểm cuối 'net.pipe: //localhost/MyApp.MyID'. ---> System.IO.PipeException: Một điểm cuối đường ống tồn tại cho '\. \ Pipe ... guid ...', nhưng kết nối thất bại: Access bị từ chối. (5, 0x5)

Chạy bổ trợ theo chế độ được bảo vệ là một kịch bản mà tôi phải hỗ trợ. Sự hiểu biết của tôi là nếu tôi giảm mức độ toàn vẹn của tên đường ống, thì trình bổ sung IE của tôi sẽ được phép nói qua nó. Câu hỏi của tôi là làm thế nào để làm điều đó. Tôi có những thứ thiết lập để sử dụng WCF, và tốt nhất là muốn giữ nó theo cách đó. Tôi có thể làm WCF tạo ống có tên với mức toàn vẹn thấp hơn không? Tôi viết mã gì để thực hiện điều đó?

Trả lời

7

Tôi không nghĩ rằng điều này là có thể.

Vấn đề là nhãn toàn vẹn phải được chỉ định trong bộ mô tả bảo mật được cung cấp khi Ống được đặt tên được tạo. Trong NetNamedPipeBinding tiêu chuẩn, lệnh gọi tới CreateNamedPipe xảy ra bên trong phương thức riêng CreatePipe() của lớp WCF nội bộ System.ServiceModel.Channels.PipeConnectionListener. Tôi không thể thấy cách thay đổi cách nó chỉ định bộ mô tả bảo mật ban đầu cho đường ống.

Xem this question and answer để biết phác thảo những gì chúng tôi cần đạt được.

Viết phần tử ràng buộc vận chuyển đường ống có tên tùy chỉnh từ đầu dường như là cách duy nhất hiện tại để làm tròn điều này, thất bại mà chúng ta sẽ phải đợi Microsoft thêm một số tính năng cho phép trong phiên bản WCF tương lai. Nếu bạn có quyền truy cập vào Microsoft Connect, bạn có thể add your voice to the others requesting this feature.

EDIT: Tôi đã quá bi quan. Bây giờ tôi đã tìm ra cách để làm điều này. Điều quan trọng là nó bật ra bạn không nhất thiết phải xác định nhãn toàn vẹn trong mô tả bảo mật khi đường ống được tạo ra - nhưng bạn phải sửa đổi SACL bằng cách sử dụng tay cầm được trả về từ CreateNamedPipe khi người nghe là đã mở - nghĩa là xử lý phía máy chủ đầu tiên cho đường ống. Sử dụng bất kỳ tay cầm nào khác, nỗ lực thêm nhãn toàn vẹn luôn không thành công, vì tham số cờ dwOpenMode để CreateNamedPipe quá tải việc sử dụng một trong các bit có nghĩa là cả hai FILE_FLAG_FIRST_PIPE_INSTANCEWRITE_OWNER. Chúng ta cần sự cho phép truy cập thứ hai để thêm nhãn toàn vẹn, nhưng sự hiện diện của nguyên nhân trước đây làm cho cuộc gọi thất bại trên bất kỳ trường hợp nào của ống đầu tiên.

Việc giữ tay cầm ống đầu tiên không phải là việc thực hiện tầm thường. WCF squirrels nó đi trong một trường hợp của các loại System.ServiceModel.Channels.PipeConnectionListener.PendingAccept, được lưu trữ trong một danh sách duy trì bởi người nghe kết nối đường ống. Trình lắng nghe kết nối không giống với bộ lắng nghe kênh (có thể được nắm bắt đơn giản bằng cách ghi đè phương thức BuildChannelListener<> của một phần tử ràng buộc), và nó khó tiếp cận hơn nhiều. Nó liên quan đến việc sử dụng sự phản chiếu, để xác định TransportManager cho điểm cuối, giữ một tham chiếu đến trình nghe kết nối của thiết bị đầu cuối và sau đó làm việc với một chuỗi các trình nghe kết nối (thay đổi theo cấu hình truy tìm vv) cho đến khi người nghe kết nối đường ống được tìm thấy . Nếu chúng ta may mắn thì tay cầm ống đầu tiên có thể được tìm thấy trong danh sách chấp nhận đang chờ của người nghe (mặc dù có một điều kiện chủng tộc ở đây - nếu một khách hàng kết nối trước khi chúng ta nắm giữ tay cầm, nó sẽ biến mất vĩnh viễn).

Sau khi xử lý có sẵn, giảm tính toàn vẹn để cho phép khách hàng toàn vẹn thấp giao tiếp với dịch vụ chỉ là vấn đề gọi SetSecurityInfo trên tay cầm để thêm nhãn toàn vẹn.

Tôi dự định trình bày chi tiết này là một số chi tiết về số my blog sớm.