【问题标题】:ActionContext.ActionArguments Is Empty In IAuthenticationFilterActionContext.ActionArguments 在 IAuthenticationFilter 中为空
【发布时间】:2014-08-21 00:27:55
【问题描述】:

背景:

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

问题:

ActionContext.ActionArguments,我通常用来访问请求负载,当我尝试在过滤器中访问它时是空的。

问题:

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

代码:

过滤器实现:

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
{

}

谢谢!

【问题讨论】:

  • (1) 如果您(暂时)不使用 Ninject,它会起作用吗? (2) 如果您使用授权过滤器,它是否有效? (3) 可能值得一看this SO question

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


【解决方案1】:

我自己也遇到了同样的情况,如果它对任何人有帮助,你需要使用 Reflection 和 System.Web.Helpers 的 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);
    }

【讨论】:

  • 有点笨拙,但我认为它会起作用 :) 你如何托管它? IIS?自托管?
【解决方案2】:

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

【讨论】:

  • 知道了。是否可以在 AuthenticationAuthorization 过滤器中访问请求正文,还是不推荐?
  • 是的,可以在AuthenticationAuthorization 过滤器中读取请求正文,但这并不常见……所以你能描述一下你的场景吗……
猜你喜欢
  • 2019-03-25
  • 2015-06-05
  • 1970-01-01
  • 2018-01-09
  • 1970-01-01
  • 1970-01-01
  • 2014-09-01
  • 1970-01-01
  • 2015-02-16
相关资源
最近更新 更多