ActionContext.ActionArguments Is Empty In IAuthenticationFilter

☆樱花仙子☆ 提交于 2019-12-11 12:19:44

问题


Background:

I want to authenticate a POST request to my web API using an implementation of IAuthenticationFilter injected using Ninject. To authenticate a request I need access to request body.

Problem:

ActionContext.ActionArguments, which I usually use to access request payload, is empty when I try to access it inside the filter.

Question:

  1. How to access POST request payload inside an IAuthenticationFilter implementation?
  2. Why ActionContext.ActionArguments is empty inside an IAuthenticationFilter implementation, but has values if my filter implements ActionFilterAttribute?

Code:

Filter implementation:

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
    }
}

The filter is injected using Ninject when controller method has a attribute.

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

AuthenticateAttribute is an empty ActionFilterAttribute.

public class AuthenticateAttribute : ActionFilterAttribute
{

}

Thank you!


回答1:


This is expected behavior. Authentication and Authorization filters run before ModelBinding/Formatter deserialization stage, where as Action filters run after this stage.




回答2:


I struggled a bit myself with the same situation, in case it helps anyone, you need to use Reflection and System.Web.Helpers's Json.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);
    }


来源:https://stackoverflow.com/questions/24493425/actioncontext-actionarguments-is-empty-in-iauthenticationfilter

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!