2014-09-02 69 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

相关问题