2014-09-02 74 views
5

我正在使用ASP.NET MVC框架。在這個框架中,我們檢查了每個傳入請求(url)的某個鍵並將其分配給一個屬性。我們創建了一個自定義類,該類自Controller類&我們覆蓋OnActionExecuting()提供我們的自定義邏輯。在ASP.NET WEB API中讀取每個傳入請求(URL)

我們如何才能在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); 
    }  
} 

我曾嘗試在ASP.NET WEB API: - 雖然這是工作,我不知道這是正確的做法?

創建一個基本控制器

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

創建另一類它繼承ActionFilterAttribute類&我重寫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; 


      } 
    } 

查閱註冊該類

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

回答

7

您可以使用ASP.NET Web API中的消息處理程序。這是一個典型的安全scenation,當你需要從查詢字符串,URL或HTTP標頭的一些用戶令牌

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

1.當您需要簡單地從URL中提取用戶id,然後用它作爲參數您的API方法和ASP.NET的WebAPI會爲你做的工作,如

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

它對於這樣的請求

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

工作2.如果是秒請參閱http://www.asp.net/web-api/overview/security/authentication-and-authorization-in-aspnet-web-api 基本上,您將需要一些MessageHandler,或者您也可以使用篩選器屬性,它是ASP.NET Web API中的機制來攔截每個調用。

如果你需要處理每個請求,那麼MessageHandler是你的方式。你需要實現MessageHanler然後註冊它。

爲了容易說,典型的MessageHandler距離的MessageHandler或DelegatingHandler衍生自具有SendAsync方法重寫類:

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());    
    } 
} 

和從Global.asax.cs中

稱之爲

WebApiConfig.Register(GlobalConfiguration。組態);

一些例如虛擬hypotetical實現這樣的處理程序(在這裏你需要imeplement從IPrincipal的和UidIdentity從您的IIdentity UidPrincipal)

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(); 
     } 
    } 
} 

並讓一些ASP.NET的WebAPI方法或一些的WebAPI屬性訪問它

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

謝謝你的快速幫助。在發佈這個問題之前,我正在檢查這個URL,不確定這對我的情況會有什麼幫助。你能否給我更多的細節。 – SharpCoder 2014-09-02 09:50:26

+0

我試着添加一點點代碼,並讓它更清晰。你的用例是什麼?爲什麼你需要從每個請求中提取UserID? – Regfor 2014-09-02 12:41:15

+0

某些請求會將'userId'作爲查詢字符串傳遞。我只想檢查每個請求,如果查詢字符串具有'userId',我將讀取它並將其分配給'BaseController'中的'UserID'屬性。 'BaseController'將從'ApiController'繼承。而我的所有控制器都將從'BaseController'繼承。這將確保'UserID'屬性可用於所有控制器。問題是'DelegatingHandler'也是一個類,與ASP.NET MVC中提供的'IActionFilter'接口不同 – SharpCoder 2014-09-02 12:52:42

相關問題