2009-07-18 8 views
5

Tôi đang làm việc trên ứng dụng web Silverlight v3 và tôi muốn bảo mật quyền truy cập vào dịch vụ WCF mà tôi đang sử dụng để tìm nạp dữ liệu của mình. Tôi hiện đang có WCF làm việc tốt, nhưng nó không yêu cầu bất kỳ thông tin người dùng nào.WCF + Thông tin người dùng

Tôi không có kinh nghiệm với khía cạnh này của WCF, vì vậy ý ​​tưởng đầu tiên của tôi là thêm thông số tên người dùng và mật khẩu vào từng hoạt động của dịch vụ của tôi. Vấn đề tôi có với điều này là điều này sẽ đòi hỏi rất nhiều mã dự phòng, và thực tế là tên người dùng và mật khẩu sẽ được chuyển qua dây trong văn bản thuần túy.

Điều tôi muốn là cách xác định thông tin xác thực trả trước ở phía máy khách ngay sau khi tôi tạo proxy dịch vụ (Tôi đang sử dụng proxy được tạo tự động từ "Thêm tham chiếu dịch vụ").

Khi googling cho một giải pháp này, tôi chỉ có thể tìm thấy các giải pháp tương tự như ý tưởng đầu tiên của tôi (sử dụng thông số tên người dùng/mật khẩu). Làm ơn ai đó có thể chỉ cho tôi đúng hướng?

Cảm ơn!

Trả lời

7

Tên người dùng và mật khẩu này đến từ đâu? Nếu trang web của bạn đã triển khai xác thực Mẫu thì bạn có thể bỏ qua thông tin đăng nhập thiết lập và sử dụng cookie xác thực biểu mẫu.Nếu người dùng của bạn đăng nhập thì cookie sẽ di chuyển với cuộc gọi dịch vụ web. Để đọc nó ở phía bên kia, bạn cần phải thực hiện một vài thay đổi.

Trước tiên, bạn cần phải kích hoạt chế độ tương thích ASP.NET cho WCF trong phần System.ServiceModel:

<system.serviceModel> 
    <serviceHostingEnvironment aspNetCompatibilityEnabled="true" /> 
</system.serviceModel> 

Khi đã xong sau đó cho mỗi phương thức dịch vụ mà bạn muốn hiểu cookie ASP.NET thêm [AspNetCompatibilityRequirements] gán cho lớp dịch vụ của bạn

[ServiceContract] 
[AspNetCompatibilityRequirements(
    RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)] 
public class ExampleService 
{ 
} 

Bây giờ trong mỗi phương pháp bạn có thể truy cập vào đối tượng HttpContext.Current.User.Identity để khám phá bản sắc của người dùng.

Nếu bạn chỉ muốn một số phương pháp được gọi là bởi người dùng xác thực thì bạn có thể sử dụng một PrincipalPermission do đó

[OperationContract] 
[PrincipalPermission(SecurityAction.Demand, Authenticated=true)] 
public string Echo() 

Như một phần thưởng nếu bạn đang sử dụng cung cấp vai trò ASP.NET của sau đó những người cũng sẽ được áp dụng và sau đó bạn có thể sử dụng PrincipalPermission trên các phương pháp để giới hạn chúng cho các thành viên của một vai trò cụ thể:

[OperationContract] 
[PrincipalPermission(SecurityAction.Demand, Role="Administators")] 
public string NukeTheSiteFromOrbit() 

Và điều này cũng hoạt động tốt trong Silverlight2.

+0

Có vẻ tốt; Bạn có biết điều này (hoặc một cái gì đó tương tự) có thể sử dụng được không nếu sử dụng httpwebrequest thô? Tôi có một ngăn xếp RPC tùy chỉnh mà tôi muốn bảo mật theo cùng một cách (tôi có thể yêu cầu như một queston mới nếu nó là một câu trả lời không tầm thường) –

+0

Nó nên làm có; xem http://www.silverlightshow.net/items/Cookies-in-Silverlight-Web-Requests.aspx – blowdart

+0

Ta; Tôi sẽ xem xét điều đó ;-p –

0

bạn có thể chuyển một số loại đối tượng xác thực và mã hóa nó ở cấp thư với WCF. Các khía cạnh C# (http://www.postsharp.org/) sau đó có thể được sử dụng để tránh logic dự phòng. Một cách rất sạch sẽ để xử lý nó.

1

Không cuộn của riêng bạn và thêm thông số rõ ràng - đó thực sự là cách quá nhiều công việc!

Kiểm tra các tính năng bảo mật của WCF - nhiều tính năng có sẵn! Bạn có thể ví dụ: bảo mật thư và bao gồm thông tin đăng nhập bên trong thư - tất cả ra khỏi hộp, không yêu cầu mã hóa thêm bên cạnh bạn!

Kiểm tra bài viết này tuyệt vời trên WCF bảo mật bằng cách Michele Leroux Bustamante: http://www.devx.com/codemag/Article/33342

Trong trường hợp của bạn, tôi muốn đề nghị an ninh thông điệp với thông tin tên người dùng - bạn cần phải cấu hình này trên cả hai đầu:

server-side:

<bindings> 
    <basicHttpBinding> 
    <binding name="SecuredBasicHttp" > 
     <security mode="Message"> 
     <message clientCredentialType="UserName"/> 
     </security> 
    </binding> 
    </basicHttpBinding> 
</bindings> 
<services> 
    <service name="YourService"> 
    <endpoint address="http://localhost:8000/MyService" 
       binding="basicHttpBinding" 
       bindingConfiguration="SecuredBasicHttp" 
       contract="IYourService" /> 
    </service> 
</services> 

Và bạn cần phải áp dụng các thiết lập tương tự trên các mặt hàng:

<bindings> 
    <basicHttpBinding> 
    <binding name="SecuredBasicHttp" > 
     <security mode="Message"> 
     <message clientCredentialType="UserName"/> 
     </security> 
    </binding> 
    </basicHttpBinding> 
</bindings> 
<client> 
    <endpoint address="http://localhost:8000/MyService" 
       binding="basicHttpBinding" 
       bindingConfiguration="SecuredBasicHttp" 
       contract="IYourService" /> 
</client> 

Bây giờ máy chủ và khách hàng của bạn thỏa thuận về an ninh - trên máy khách, sau đó bạn muốn chỉ định tên người dùng và mật khẩu để sử dụng như thế này:

YourServiceClient client = new YourServiceClient(); 

client.ClientCredentials.UserName.UserName = "your user name"; 
client.ClientCredentials.UserName.Password = "top$secret"; 

Về phía server, bạn sẽ cần để thiết lập các thông tin xác thực người dùng này đang được xác thực như thế nào - thường là chống lại tên miền Windows (Active Directory), hoặc chống lại mô hình nhà cung cấp thành viên ASP.NET. Trong mọi trường hợp, nếu không thể xác minh thông tin xác thực người dùng đối với cửa hàng đó mà bạn xác định, cuộc gọi sẽ bị từ chối.

Hy vọng điều này sẽ giúp bảo mật một chút là một chủ đề lớn trong WCF và có rất nhiều tùy chọn - nó có thể hơi khó khăn, nhưng cuối cùng, thường thì nó có ý nghĩa! :-)

Marc

+6

Tôi không chắc chắn kịch bản nào bạn có thể làm điều này, nhưng theo kinh nghiệm của tôi, điều này không được phép trong WCF. Bạn không thể sử dụng bảo mật thông tin xác thực tên người dùng chế độ nhắn tin trong basicHttpBinding, nó không được phép bởi khuôn khổ vì thông tin đăng nhập sẽ được chuyển thành văn bản thuần túy. Bạn sẽ nhận được InvalidOperationException này: "BasicHttp binding yêu cầu BasicHttpBinding.Security.Message.ClientCredentialType phải tương đương với kiểu chứng chỉ BasicHttpMessageCredentialType.Certificate cho các thư bảo mật. Chọn Bảo mật Transport hoặc TransportWithMessageCredential cho thông tin đăng nhập UserName." – Grank