2014-09-02 32 views
5

Tôi đang sử dụng khung ASP.NET MVC. Trong khuôn khổ này, chúng tôi đã kiểm tra mọi yêu cầu (url) đến cho một số khóa và gán nó cho một thuộc tính. Chúng tôi đã tạo một lớp tùy chỉnh bắt nguồn từ Controller lớp & chúng tôi ghi đèOnActionExecuting() để cung cấp logic tùy chỉnh của chúng tôi.Đọc mọi yêu cầu (URL) trong ASP.NET WEB API

Làm cách nào chúng ta có thể đạt được điều tương tự trong ASP.NET WEB API?

//Implementation from ASP.NET MVC 

public class ApplicationController : Controller 
{  
    public string UserID { get; set; } 

    protected override void OnActionExecuting(ActionExecutingContext filterContext) 
    { 
     if (!string.IsNullOrEmpty(Request.Params["uid"])) 
      UserID = Request.Params["uid"]; 

     base.OnActionExecuting(filterContext); 
    }  
} 

Những gì tôi đã cố gắng trong ASP.NET WEB API: - Mặc dù đây đang làm việc, tôi tự hỏi nếu điều này là cách tiếp cận đúng không?

Tạo một bộ điều khiển cơ sở

public class BaseApiController : ApiController 
    { 
     public string UserID { get; set; } 
    } 

Tạo một lớp mà được thừa hưởng ActionFilterAttribute lớp & tôi ghi đè OnActionExecuting()

public class TokenFilterAttribute : ActionFilterAttribute 
    { 
     public override void OnActionExecuting(System.Web.Http.Controllers.HttpActionContext actionContext) 
      { 
       var queryString = actionContext.Request.RequestUri.Query; 
       var items = HttpUtility.ParseQueryString(queryString); 
       var userId = items["uid"]; 

       ((MyApi.Data.Controllers.BaseApiController)(actionContext.ControllerContext.Controller)).UserID = userId; 


      } 
    } 

Bây giờ đăng ký lớp này

public static void Register(HttpConfiguration config) 
{ 
    config.Filters.Add(new TokenFilterAttribute()); 
} 

Trả lời

7

Bạn có thể sử dụng trình xử lý tin nhắn từ ASP.NET Web API. Nó là một scenation an ninh điển hình, khi bạn cần phải nhận được một số token của user từ chuỗi truy vấn, URL hoặc HTTP Header

http://www.asp.net/web-api/overview/advanced/http-message-handlers

1. Khi bạn cần chỉ đơn giản để trích xuất userId từ URL, sau đó sử dụng nó như là tham số cho phương pháp Api của bạn và ASP.NET WebAPI sẽ làm việc cho bạn, như

[HttpGet, Route("{userId}/roles")]  
public UserRoles GetUserRoles(string userId, [FromUri] bool isExternalUser = true) 

nó làm việc cho yêu cầu đó

http://.../15222/roles?isExternalUser=false 

2.Nếu nó là giây Kịch bản thuần túy, vui lòng tham khảo http://www.asp.net/web-api/overview/security/authentication-and-authorization-in-aspnet-web-api Về cơ bản bạn sẽ cần một số MessageHandler hoặc bạn cũng có thể sử dụng các thuộc tính lọc, đó là cơ chế trong ASP.NET Web API để chặn từng cuộc gọi.

Nếu bạn cần xử lý từng yêu cầu thì MessageHandler là cách của bạn. Bạn cần thực hiện MessageHanler và sau đó đăng ký nó.

Để nói một cách dễ dàng, MessageHandler điển hình là lớp có nguồn gốc từ MessageHandler hoặc DelegatingHandler với phương pháp SendAsync overriden:

class AuthenticationHandler : DelegatingHandler 
{ 
    protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) 
    { 
     // Your code here 
     return base.SendAsync(request, cancellationToken); 
    } 
} 

And you need register it 

static class WebApiConfig 
{ 
    public static void Register(HttpConfiguration config) 
    {     
     // Other code for WebAPI registerations here 
     config.MessageHandlers.Add(new AuthenticationHandler());    
    } 
} 

và gọi nó là từ Global.asax.cs

WebApiConfig.Register (GlobalConfiguration.Cấu hình);

Một số ví dụ thực hiện hypotetical giả của bộ xử lý như vậy (ở đây bạn cần phải imeplement UidPrincipal của bạn từ IPrincipal và UidIdentity từ IIdentity)

public class AuthenticationHandler : DelegatingHandler 
{  
    protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) 
    { 
     try 
     { 
      var queryString = actionContext.Request.RequestUri.Query; 
      var items = HttpUtility.ParseQueryString(queryString); 
      var userId = items["uid"]; 

      // Here check your UID and maybe some token, just dummy logic 
      if (userId == "D8CD2165-52C0-41E1-937F-054F24266B65") 
      {   
       IPrincipal principal = new UidPrincipal(new UidIdentity(uid), null); 

       // HttpContext exist only when hosting as asp.net web application in IIS or IISExpress 
       if (HttpContext.Current != null) 
       { 
        HttpContext.Current.User = principal; 
       } 
       else 
       { 
        Thread.CurrentPrincipal = principal; 
       } 
       return base.SendAsync(request, cancellationToken); 
      } 
      catch (Exception ex) 
      { 
       this.Log().Warn(ex.ToString()); 
       return this.SendUnauthorizedResponse(ex.Message); 
      } 
     } 
     else 
     { 
      return this.SendUnauthorizedResponse(); 
     } 
     } 
     catch (SecurityTokenValidationException) 
     { 
      return this.SendUnauthorizedResponse(); 
     } 
    } 
} 

Và cho phép truy cập nó từ một số phương pháp ASP.NET WebAPI hoặc một số tài sản trong WebAPI lớp

var uid = ((UidIdentity)User.Identity).Uid 
+0

Cảm ơn bạn đã trợ giúp nhanh. Trước khi đăng câu hỏi tôi đã kiểm tra URL này và không chắc chắn điều này sẽ giúp ích gì trong trường hợp của tôi. Bạn có thể vui lòng cho tôi biết thêm chi tiết không. – SharpCoder

+0

Tôi đã cố gắng thêm một chút mã và làm cho nó rõ ràng hơn cho bạn. Trường hợp sử dụng của bạn là gì? Tại sao bạn cần trích xuất UserID từ mỗi yêu cầu? – Regfor

+0

Một số yêu cầu sẽ có 'userId' được chuyển thành chuỗi truy vấn. Tất cả những gì tôi muốn là kiểm tra mọi yêu cầu và nếu chuỗi truy vấn có 'userId', tôi sẽ đọc nó và gán nó cho thuộc tính' UserID' trong 'BaseController'. 'BaseController' sẽ kế thừa từ' ApiController'. Và tất cả các bộ điều khiển của tôi sẽ kế thừa từ 'BaseController'. Mà sẽ đảm bảo tài sản 'UserID' có sẵn cho tất cả các bộ điều khiển. Vấn đề là 'DelegatingHandler' cũng là một lớp, không giống như giao diện' IActionFilter' có sẵn trong ASP.NET MVC – SharpCoder

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