在IAuthenticationFilter中,ActionContext.ActionArguments为空

时间:2014-06-30 15:15:07

标签: c# asp.net authentication asp.net-web-api2 action-filter

背景

我想使用Ninject注入IAuthenticationFilter的实现来验证对我的Web API的POST请求。要验证请求,我需要访问请求正文。

问题:

当我尝试在过滤器中访问请求时,我通常用来访问请求有效负载的

ActionContext.ActionArguments为空。

问题:

  1. 如何在IAuthenticationFilter实施中访问POST请求有效负载?
  2. 为什么ActionContext.ActionArgumentsIAuthenticationFilter实现中为空,但如果我的过滤器实现了ActionFilterAttribute,则会有值?
  3. 代码:

    过滤器实施:

    public class AuthenticateFilter : IAuthenticationFilter
    {
        private const string AuthenticationHeader = "X-Auth-Token";
        private const string UserHeader = "X-Auth-User";
    
        private readonly ILog log;
    
        public AuthenticateFilter(ILog log)
        {
            this.log = log;
        }
    
        public Task AuthenticateAsync(HttpAuthenticationContext context, 
                                      CancellationToken cancellationToken)
        {
            // context.ActionContext.ActionArguments is empty
    
            if (!IsAuthenticated(context))
            {
                context.ErrorResult = 
                    new StatusCodeResult(HttpStatusCode.Unauthorized, 
                                         context.Request);
            }
    
            return Task.FromResult(0);
        }
    
        public Task ChallengeAsync(HttpAuthenticationChallengeContext context,
                                   CancellationToken cancellationToken)
        {
            context.Result = 
                new StatusCodeResult(HttpStatusCode.Unauthorized, 
                                     context.Request);
    
            return Task.FromResult(0);
        }
    
        private bool IsAuthenticated(HttpAuthenticationContext context)
        {
            // Authentication code here
            // context.ActionContext.ActionArguments is empty
        }
    }
    

    当控制器方法具有属性时,使用Ninject注入过滤器。

    kernel.BindHttpFilter<AuthenticateFilter>(FilterScope.Action)
          .WhenActionMethodHas<AuthenticateAttribute>();
    

    AuthenticateAttribute为空ActionFilterAttribute

    public class AuthenticateAttribute : ActionFilterAttribute
    {
    
    }
    

    谢谢!

2 个答案:

答案 0 :(得分:2)

这是预期的行为。 AuthenticationAuthorization过滤器在ModelBinding / Formatter反序列化阶段之前运行,其中Action过滤器在此阶段之后运行。

答案 1 :(得分:2)

我在相同的情况下有点挣扎,如果它有助于任何人,你需要使用Reflection和System.Web.Helpers&#39; Jcode.Decode:

 public Task AuthenticateAsync(HttpAuthenticationContext context, CancellationToken cancellationToken)
    {
        HttpRequestMessage request = context.Request;
        var content = request.Content.ReadAsAsync(typeof(Object)).Result.ToString();
        var methodInfo = ((ReflectedHttpActionDescriptor)request.Properties["MS_HttpActionDescriptor"]).MethodInfo; // get the method descriptor

        if (methodInfo.GetParameters().Any())  //this will get the parameter types
        {
             var parameterType = methodInfo.GetParameters().First().ParameterType; //you iterate can through the parameters if you need
             var casted = Json.Decode(content, parameterType);  //convert the json content into the previous type (your parameter)
             //do something with your populated object :)
        }

        return Task.FromResult(context.Request);
    }