2012-07-03 37 views
13

Tôi làm cách nào để sử dụng Trình quản lý vai trò trong Dịch vụ WCF?Tôi làm cách nào để sử dụng Trình quản lý vai trò trong Dịch vụ WCF?

Trong ứng dụng .NET của tôi, tôi có thể giới hạn một lớp hoặc phương thức bằng thẻ [Authorize(Roles=)]. Làm thế nào tôi có thể kích hoạt tính năng này cho Dịch vụ WCF của tôi?

Tôi hiện đang có các thiết lập ràng buộc sau cho mỗi thiết bị đầu cuối:

<webHttpBinding> 
    <binding name="TransportSecurity" maxReceivedMessageSize="5242880"> 
     <security mode="Transport"> 
     <transport clientCredentialType="None"/> 
     </security> 
    </binding> 
    </webHttpBinding> 

Vì tôi muốn có người dùng đăng nhập vào và nhận được một cookie với hiệu trưởng, tôi cần phải thay đổi điều này khác loại clientCredentialType ?

Sửa 1:

Đây là sử dụng REST, không SOAP. Nó cũng lưu ý rằng điều quan trọng là nó hoạt động với các thiết bị di động (android, iPhone) và có thể sử dụng cookie để duy trì một phiên. Cho đến nay, tôi đã không thể làm việc này, sử dụng đoạn mã sau/config:

Config File:

<roleManager enabled="true" defaultProvider="ActiveDirectoryRoleProvider" cacheRolesInCookie="true" cookieName="RoleCookie" cookiePath="/" cookieTimeout="30" cookieRequireSSL="false" cookieSlidingExpiration="true" createPersistentCookie="false" cookieProtection="All"> 
     <providers> 
     <clear /> 
     <add name="ActiveDirectoryRoleProvider" connectionStringName="ADServices" connectionUsername="" connectionPassword="" attributeMapUsername="sAMAccountName" type="" /> 
     </providers> 
    </roleManager> 

    <membership defaultProvider="MembershipADProvider"> 
     <providers> 
     <add name="MembershipADProvider" type="System.Web.Security.ActiveDirectoryMembershipProvider, System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" applicationName="" connectionStringName="ADServices" connectionUsername="" connectionPassword="" attributeMapUsername="sAMAccountName" /> 
     </providers> 
    </membership> 

<bindings> 
    <webHttpBinding> <!-- webHttpBinding is for REST --> 
    <binding name="TransportSecurity" maxReceivedMessageSize="5242880"> 
     <security mode="Transport"> 
     </security> 
    </binding> 
    </webHttpBinding> 
</bindings> 

<behaviors> 
    <endpointBehaviors> 
    <behavior name="web"> 
     <webHttp /> 
    </behavior> 
    </endpointBehaviors> 
    <serviceBehaviors> 
    <behavior name="ServiceBehaviour"> 
     <serviceMetadata httpGetEnabled="false" httpsGetEnabled="true" /> 
     <serviceDebug httpHelpPageEnabled="true" includeExceptionDetailInFaults="true" /> 
     <serviceAuthorization principalPermissionMode="UseAspNetRoles" roleProviderName="ActiveDirectoryRoleProvider" /> 
     <serviceCredentials> 
     <userNameAuthentication userNamePasswordValidationMode="MembershipProvider" membershipProviderName="MembershipADProvider" /> 
     </serviceCredentials> 
    </behavior> 
    </serviceBehaviors> 
</behaviors> 

public void SignIn2(string userName, bool createPersistentCookie) 
    { 
     if (String.IsNullOrEmpty(userName)) throw new ArgumentException("Value cannot be null or empty.", "userName"); 

     // put the attributes in a string for userdata 
     string userData = ""; 

     // create the ticket 
     FormsAuthenticationTicket authTicket = new FormsAuthenticationTicket(1, 
               userName, 
               DateTime.Now, 
               DateTime.Now.AddMinutes(240), 
               createPersistentCookie, 
               userData); 

     // Now encrypt the ticket. 
     string encryptedTicket = FormsAuthentication.Encrypt(authTicket); 

     // Create a cookie and add the encrypted ticket to the cookie as data. 
     HttpCookie authCookie = new HttpCookie(FormsAuthentication.FormsCookieName, encryptedTicket); 

     // add the cookie 
     HttpContext.Current.Response.Cookies.Add(authCookie); 
    } 

Bây giờ sử dụng chủ yếu Giấy phép, tôi nhận được SecurityException (Tôi biết vai trò có hiệu lực trên máy chủ)

[PrincipalPermission(SecurityAction.Demand, Role = Constants.RoleUser)] 
    public Message TestRoles() 
    { 
     var context = NetworkHelper.GetWebOperationContext(); 

     return context.CreateTextResponse("You have successfully activated the endpoint."); 
    } 

Tôi có thiếu một bước quan trọng ở đây không?

Trả lời

9

Tôi đã viết a blog post về cách sử dụng xác thực ASP.NET với WCF; các ý chính của nó là bạn muốn sử dụng các ràng buộc sau:

<basicHttpBinding> 
    <binding> 
     <security mode="TransportWithMessageCredential"> 
     <message clientCredentialType="UserName"/> 
     </security> 
    </binding> 
    </basicHttpBinding> 

Bạn cũng phải áp dụng những điều sau serviceBehavior

<behavior> 
     <!-- no need for http get; 
      but https get exposes endpoint over SSL/TLS--> 
     <serviceMetadata httpGetEnabled="false" httpsGetEnabled="true"/> 
     <!-- the authorization and credentials elements tie 
     this behavior (defined as the default behavior) to 
     the ASP.NET membership framework--> 
     <serviceAuthorization 
      principalPermissionMode="UseAspNetRoles" 
      roleProviderName="AspNetRoleProvider" /> 
     <serviceCredentials> 
     <userNameAuthentication 
      userNamePasswordValidationMode="MembershipProvider" 
      membershipProviderName="AspNetMembershipProvider" /> 
     </serviceCredentials> 
    </behavior> 

Một điểm quan trọng cần lưu ý là bạn phải sử dụng SSL nếu bạn sẽ bảo vệ WCF bằng tên và mật khẩu, đó là lý do tại sao bảo mật giao thông được chỉ định.

Khi bạn đã thực hiện việc này, bạn sẽ có thể sử dụng thuộc tính PrincipalPermission để đảm bảo các phương pháp dịch vụ của mình.

+0

Tôi thấy, tôi thấy rằng thuộc tính 'Authorize' là MVC-centric. Tôi sẽ phải sử dụng 'PrincipalPermission', tôi cho rằng nó hoạt động theo cách rất giống nhau? – Cody

+0

+1: Câu trả lời hay! Rõ ràng Microsoft đã theo chủ đề này với một bài viết về MSDN về việc sử dụng các nhà cung cấp vai trò với WCF: http://msdn.microsoft.com/en-us/library/aa702542.aspx – reSPAWNed

+0

Xin chào.Có thể bạn hãy xem câu hỏi này : https: //stackoverflow.com/questions/45770217/my-customauthorizationpolicy-evaluate-method-never-fires –

2

Tôi nghĩ rằng một cái gì đó như thế này sẽ cung cấp những gì bạn đang tìm kiếm:

// Only members of the SpecialClients group can call this method. 
[PrincipalPermission(SecurityAction.Demand, Role = "SpecialClients")] 
public void DoSomething() 
{ 
} 

Bạn có thể tìm thấy một bài viết tốt về các tùy chọn khác nhau cho việc thiết lập dịch vụ của bạn ở đây: MSDN Article. Bạn có thể muốn cập nhật cấu hình của mình bằng một cái gì đó như:

<security mode="TransportWithMessageCredential" > 
    <transport clientCredentialType="Windows" /> 
</security> 
2

Hai năm trước, tôi đã viết blog về tích hợp wcf với xác thực biểu mẫu và thuộc tính quyền chính.Tôi tin rằng bạn sẽ tìm thấy điều này hữu ích:

http://netpl.blogspot.com/2010/04/aspnet-forms-authentication-sharing-for.html

+0

Bạn không chắc chắn điều này sẽ giúp ích trong trường hợp của tôi. – Cody

+0

Những gì bạn bỏ lỡ so với cách tiếp cận của tôi: 1) bạn không đặt threadprincipal thành context.user 2) bạn không có khả năng tương thích asp.net 3) bạn cũng nên remand Authenticated = true trong PrincipalPermission của bạn ngoài các vai trò cụ thể –

+0

Tôi có tất cả những điều này được thiết lập và nó không hoạt động. – Cody

1

séc ra câu hỏi này Passing FormsAuthentication cookie to a WCF service. Điểm chính là cookie xác thực không thể gửi hoặc nhận được vì mã miền/cài đặt asp/khóa mã hóa auth. Tôi khuyên bạn nên đổ giá trị cookie đó cho mục đích gỡ lỗi Request.Cookies [". ASPXAUTH"].

3

Tôi đã gặp vấn đề tương tự với hiệu trưởng, một thời gian dài trước đây. Tôi không nhớ chi tiết, nhưng hãy thử điều này, từ dự án rất cũ của tôi:

i. Bạn phải thêm lớp 2 helper:


using System.Web; 
using System.IdentityModel.Claims; 
using System.IdentityModel.Policy; 

namespace TicketingCore 
{ 
    public class HttpContextPrincipalPolicy : IAuthorizationPolicy 
    { 
     public bool Evaluate(EvaluationContext evaluationContext, ref object state) 
     { 
      HttpContext context = HttpContext.Current; 

      if (context != null) 
      { 
       evaluationContext.Properties["Principal"] = context.User; 
      } 

      return true; 
     } 

     public System.IdentityModel.Claims.ClaimSet Issuer 
     { 
      get { return ClaimSet.System; } 
     } 

     public string Id 
     { 
      get { return "TicketingCore HttpContextPrincipalPolicy"; } 
     } 
    } 
} 


using System; 
using System.Collections.Generic; 
using System.IdentityModel.Claims; 
using System.IdentityModel.Policy; 
using System.Text; 
using System.Web; 
using System.Security.Principal; 

namespace TicketingCore 
{ 
    // syncs ServiceSecurityContext.PrimaryIdentity in WCF with whatever is set 
    // by the HTTP pipeline on Context.User.Identity (optional) 
    public class HttpContextIdentityPolicy : IAuthorizationPolicy 
    { 
     public bool Evaluate(EvaluationContext evaluationContext, ref object state) 
     { 
      HttpContext context = HttpContext.Current; 

      if (context != null) 
      { 
       // set the identity (for PrimaryIdentity) 
       evaluationContext.Properties["Identities"] = 
        new List<IIdentity>() { context.User.Identity }; 

       // add a claim set containing the client name 
       Claim name = Claim.CreateNameClaim(context.User.Identity.Name); 
       ClaimSet set = new DefaultClaimSet(name); 
       evaluationContext.AddClaimSet(this, set); 
      } 

      return true; 
     } 

     public System.IdentityModel.Claims.ClaimSet Issuer 
     { 
      get { return ClaimSet.System; } 
     } 

     public string Id 
     { 
      get { return "TicketingCore HttpContextIdentityPolicy"; } 
     } 
    } 
} 

ii. Thay đổi webconfig để thêm 2 chính sách này, đây là cấu hình của tôi (định dạng: add policyType = "namespace.class, assembly")

<serviceBehaviors> 
    <behavior name="ServiceBehavior"> 
     <serviceCredentials> 
     <userNameAuthentication userNamePasswordValidationMode="MembershipProvider" membershipProviderName="SQLMembershipProvider"/> 
     </serviceCredentials> 
     <serviceAuthorization principalPermissionMode="Custom"> 
     <authorizationPolicies> 
      <add policyType="TicketingCore.HttpContextIdentityPolicy, TicketingCore"/> 
      <add policyType="TicketingCore.HttpContextPrincipalPolicy, TicketingCore"/> 
     </authorizationPolicies> 
     </serviceAuthorization> 
     <serviceMetadata httpGetEnabled="true"/> 
     <serviceDebug includeExceptionDetailInFaults="false"/> 
    </behavior> 
    </serviceBehaviors> 

iii. Đảm bảo cookie và vai trò đang hoạt động tốt

Lưu ý: Tôi cũng không nhớ nguồn của giải pháp, bạn có thể cần phải google tên lớp để tìm hiểu, hy vọng sẽ hữu ích cho bạn, chúc bạn may mắn!

+0

Đây là ví dụ hoàn chỉnh nhất trên Internet và có vẻ là cách chính xác nhất để thực hiện ủy quyền bằng Xác thực Mẫu trong dịch vụ WCF. Một vấn đề liên quan là làm thế nào để thực hiện xác thực trong dịch vụ gọi chính nó và trả về một lỗi 401 thay vì dựa vào một IIS web.config để từ chối người dùng nặc danh truy cập vào thư mục con dịch vụ. – Monstieur

+0

Dự án mẫu ở bất kỳ đâu? – Rhyous

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