2012-03-10 9 views
5

Tìm kiếm một lời khuyên nhỏ (hoặc thậm chí có thể là câu trả lời trực tiếp).Truyền HttpContext.Current.User.Identity tới WCF

Tôi có trang web MVC3. Tôi cũng có một tập hợp các dịch vụ WCF đang chạy (hiện tại mọi thứ đều nằm trên cùng một hộp).

Tôi đang cố gắng để làm là xác thực ứng dụng khách (phần đó hoạt động tốt), sau đó chuyển người dùng đã xác thực đó cho các cuộc gọi WCF khác nhau.

Tại thời điểm tôi đã nối phương pháp Application_AuthenticateRequest() trong Global.Asax, mà nắm để tạo ra một mới GenericIdentity & GenericPrincipal, sau đó gán chính đó để HttpContext.Current.User:

... 
GenericIdentity identity = new GenericIdentity(userName); 
GenericPrincipal principal = new GenericPrincipal(identity, null); 
HttpContext.Current.User = principal; 
... 

Và một phần điều đó dường như làm việc tốt như tốt.

Nhưng khi tôi nhấn dịch vụ của mình, tôi đã mất hoàn toàn người dùng mà tôi đã đặt. Các giá trị trống hoặc sai.

Điều chính tôi nhận thấy là ở phía khách hàng, đối tượng HttpContext.Current.User.Identity thuộc loại {System.Web.Security.FormsIdentity}, nhưng trong dịch vụ thuộc loại {System.Security.Principal.WindowsIdentity}.

Dựa trên một số nội dung tôi đã đọc, có vẻ như chỉ cần sửa đổi web.config của tôi để nó chứa aspNetCompatibilityEnabled="true" có thể đủ để làm cho công việc này hoạt động bình thường. Nhưng đó không phải những gì tôi thấy. Vì vậy, hoặc là tôi không hiểu tất cả mọi thứ (một khả năng rất tốt) hoặc tôi đã có một cái gì đó hơi say lên (một khả năng tốt).

Vì vậy, câu hỏi của tôi. Điều này thậm chí có thể, và nếu có - suy nghĩ về những gì tôi đang mất tích? Tôi nhận thấy một vài người khác đã đăng nội dung nào đó tương tự nhưng chưa bao giờ nhận được câu trả lời rõ ràng (xem herehere).

Bất kỳ đề xuất nào được đánh giá rất nhiều.

+0

Thật lạ khi bạn nói rằng bạn thấy một 'FormsIdentity' khi bạn đặt cụ thể một' GenericIdentity' trên ngữ cảnh người dùng hiện tại. Bạn đã trộn ở đó chưa? –

Trả lời

2

Tôi thực sự không thể trả lời trực tiếp câu hỏi của bạn nhưng hy vọng sẽ giúp bạn tìm câu trả lời rõ ràng.

Bạn có 2 lớp dịch vụ và dường như yêu cầu của bạn là chia sẻ danh tính Xác thực giữa tất cả các lớp.

Vì vậy, về nguyên tắc, bạn cần (ít nhất) các cơ chế hoặc thuật toán hoặc kỹ thuật xác thực tương tự để đạt được điều này. Nhưng tại thời điểm này bạn không sử dụng cùng một (và bạn nhận thấy khi bạn nhìn thấy một FormsIdentityWindowsIdentity ở đó).

Sự kiện:

  • Bạn sẽ cần các cơ chế xác thực tương tự.
  • Bất cứ cơ chế nào bạn sử dụng, cần hỗ trợ hop thứ 3 mà bạn muốn thực hiện (nghĩa là bạn có thể sử dụng danh tính của người dùng với dịch vụ thứ 3 mà không thực sự có thông tin đăng nhập để xác thực lại).

vấn đề:

  • Nếu bạn tiếp tục sử dụng hình thức xác thực, sau đó bạn sẽ cần phải xác thực lại với dịch vụ WCF của bạn (và dĩ nhiên là cung cấp thông tin nhận dạng, thisthể giúp đỡ).Điều này tôi thấy khó làm trừ khi bạn giữ mật khẩu mà Người dùng đã sử dụng để xác thực anh ta/cô ta thường là một ý tưởng tồi.
  • Nếu bạn tiếp tục sử dụng Xác thực Windows cho trang web của mình, thì bạn sẽ gặp sự cố nếu người dùng đang đăng nhập từ Mạng nội bộ. Điều thú vị với Kerberos (Active Directory sử dụng Kerberos) là nó cho phép người dùng truy cập tài nguyên từ xa mà không cần xác thực lại ... nhưng Mã nhận dạng người dùng này chỉ tốt cho 1 hop. Trong khi các dịch vụ WCF và MVC của bạn nằm trên cùng một máy chủ, nó sẽ hoạt động nhưng nếu cuối cùng bạn lấy dịch vụ WCF đi ... đó là ranh giới hộp thứ 3 ... bước thứ 3 và vé Kerberos sẽ không đủ tốt.

... Vì vậy, là không biết gì về yêu cầu của bạn, đầu tiên tôi sẽ đề nghị bạn:

  • Hãy quên đi việc xác thực trên lớp WCF bạn
  • Hãy truy cập dịch vụ WCF của bạn riêng tư (làm việc kỹ năng Networking của bạn. .. firewalls et al). Tôi bắt đầu bằng cách chạy WCF trên một trang web IIS riêng biệt mà không nghe cổng 80 (hoặc 443) và chắc chắn rằng Firewall chặn truy cập vào cổng WCF mới của bạn từ các IP bên ngoài mạng LAN của bạn (hoặc thậm chí tốt hơn, bên ngoài màu trắng của bạn) danh sách (localhost cho bây giờ)).
  • Chỉ định danh tính người dùng làm thông số của mọi cuộc gọi WCF. Hoặc nếu bạn cảm thấy hoang dã, hãy tìm cách xác định danh tính người dùng thông qua các tiêu đề SOAP (nếu WCF của bạn sử dụng SOAP). Tiêu đề tùy chỉnh cũng chỉ hoạt động tốt. Bạn sẽ tin tưởng sau đó trang web của bạn để thử thách chính xác và xác thực người dùng trước khi cấp cho họ quyền truy cập vào các dịch vụ WCF của bạn.

Tôi đã nhìn thấy điều này đang chạy nhiều lần ngay bây giờ. Không có xác thực trên một dịch vụ riêng tư là một thỏa thuận hiệu suất tốt, nhưng bạn cần phải đề phòng nguyên nhân nói chung, hầu hết các cuộc tấn công CNTT đến từ mạng LAN nội bộ.