例外:在WebAPI 2中实现自定义筛选器时,给定的筛选器必须实现以下一个或多个筛选器接口

时间:2016-09-27 06:12:00

标签: c# asp.net-web-api

我正在尝试构建自定义过滤器以进行身份​​验证,但是当我尝试运行我的WebAPI解决方案时,我正在运行此问题:

  

给定的过滤器实例必须实现以下一项或多项   过滤器接口:System.Web.Mvc.IAuthorizationFilter,   System.Web.Mvc.IActionFilter,System.Web.Mvc.IResultFilter,   System.Web.Mvc.IExceptionFilter,   System.Web.Mvc.Filters.IAuthenticationFilter。

FilterConfig类中出现错误:

public class FilterConfig
{
   public static void RegisterGlobalFilters(GlobalFilterCollection filters)
   {
        filters.Add(new HandleErrorAttribute());
        filters.Add(new AuthAttribute());
   }
}

在我尝试将AuthAttribute添加到过滤器的行中。

这是整个AuthAttribute类:

using Examino.Business;
using System;
using System.Collections.Generic;
using System.Diagnostics.Contracts;
using System.IdentityModel;
using System.IdentityModel.Tokens;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Threading;
using System.Web;
using System.Web.Http;
using System.Web.Http.Controllers;

namespace Examino.API.Filters
{
    public class AuthAttribute : AuthorizeAttribute
    {
        public ITokenProviderService TokenProviderService { get; set; }

        public override void OnAuthorization(HttpActionContext actionContext)
        {
            SetDependencies(actionContext);

            if (!IsAuthorized(actionContext) && !SkipAuthorization(actionContext))
            {
                if (Authenticate(actionContext) == AuthenticationErrors.UNAUTHORIZED)
                {
                    actionContext.Response = actionContext.Request.CreateResponse(HttpStatusCode.Unauthorized,
                        new HttpResponseMessage(HttpStatusCode.Unauthorized));
                }
                else if (Authenticate(actionContext) == AuthenticationErrors.TOKEN_EXPIRED)
                {
                    actionContext.Response = actionContext.Request.CreateResponse(HttpStatusCode.Unauthorized,
                        //token expired status code?
                        new HttpResponseMessage(HttpStatusCode.Unauthorized));
                }
            }
        }

        private void SetDependencies(HttpActionContext actionContext)
        {
            var requestScope = actionContext.Request.GetDependencyScope();

            if (TokenProviderService == null)
            {
                TokenProviderService = requestScope.GetService(typeof(ITokenProviderService)) as ITokenProviderService;
            }
        }

        private AuthenticationErrors Authenticate(HttpActionContext actionContext)
        {
            IEnumerable<string> authHeaderValues;
            actionContext.Request.Headers.TryGetValues("Authorization", out authHeaderValues);

            try
            {
                if (authHeaderValues != null)
                {
                    string bearerToken = authHeaderValues.ElementAt(0);
                    string token = bearerToken.StartsWith("Bearer ") ? bearerToken.Substring(7) : bearerToken;

                    Thread.CurrentPrincipal = TokenProviderService.ValidateJwtToken(token);
                    if (Thread.CurrentPrincipal != null)
                    {
                        return AuthenticationErrors.AUTHORIZED;
                    }
                }
            }
            catch (SecurityTokenExpiredException)
            {
                return AuthenticationErrors.TOKEN_EXPIRED;
            }
            catch (Exception)
            {
                return AuthenticationErrors.UNAUTHORIZED;
            }

            return AuthenticationErrors.UNAUTHORIZED;
        }

        private bool SkipAuthorization(HttpActionContext actionContext)
        {
            Contract.Assert(actionContext != null);

            return actionContext.ActionDescriptor.GetCustomAttributes<AllowAnonymousAttribute>().Any()
                || actionContext.ControllerContext.ControllerDescriptor.GetCustomAttributes<AllowAnonymousAttribute>().Any();
        }

        private enum AuthenticationErrors
        {
            UNAUTHORIZED,
            TOKEN_EXPIRED,
            AUTHORIZED
        }
    }
}

如您所见,它继承自AuthorizeAttribute类。

这是一个堆栈跟踪:

  

[InvalidOperationException:给定的过滤器实例必须实现   一个或多个以下过滤器接口:   System.Web.Mvc.IAuthorizationFilter,System.Web.Mvc.IActionFilter,   System.Web.Mvc.IResultFilter,System.Web.Mvc.IExceptionFilter,   System.Web.Mvc.Filters.IAuthenticationFilter]
  System.Web.Mvc.GlobalFilterCollection.ValidateFilterInstance(对象   例)+403
  System.Web.Mvc.GlobalFilterCollection.AddInternal(Object filter,   Nullable`1 order)+26
  System.Web.Mvc.GlobalFilterCollection.Add(Object filter)+31
  Examino.API.FilterConfig.RegisterGlobalFilters(GlobalFilterCollection   过滤器)在C:\ examino \ src \ Examino.API \ App_Start \ FilterConfig.cs:12
  Examino.API.WebApiApplication.Application_Start()in   C:\ examino \ SRC \ Examino.API \ Global.asax.cs中:22

     

[HttpException(0x80004005):给定的过滤器实例必须实现   一个或多个以下过滤器接口:   System.Web.Mvc.IAuthorizationFilter,System.Web.Mvc.IActionFilter,   System.Web.Mvc.IResultFilter,System.Web.Mvc.IExceptionFilter,   System.Web.Mvc.Filters.IAuthenticationFilter]
  System.Web.HttpApplicationFactory.EnsureAppStartCalledForIntegratedMode(HttpContext的   上下文,HttpApplication app)+540
  System.Web.HttpApplication.RegisterEventSubscriptionsWithIIS(IntPtr的   appContext,HttpContext上下文,MethodInfo []处理程序)+186
  System.Web.HttpApplication.InitSpecial(HttpApplicationState状态,   MethodInfo [] handlers,IntPtr appContext,HttpContext context)+172
  System.Web.HttpApplicationFactory.GetSpecialApplicationInstance(IntPtr的   appContext,HttpContext context)+402
  System.Web.Hosting.PipelineRuntime.InitializeApplication(IntPtr的   appContext)+343

     

[HttpException(0x80004005):给定的过滤器实例必须实现   一个或多个以下过滤器接口:   System.Web.Mvc.IAuthorizationFilter,System.Web.Mvc.IActionFilter,   System.Web.Mvc.IResultFilter,System.Web.Mvc.IExceptionFilter,   System.Web.Mvc.Filters.IAuthenticationFilter]
  System.Web.HttpRuntime.FirstRequestInit(HttpContext context)+539
  System.Web.HttpRuntime.EnsureFirstRequestInit(HttpContext context)   +125 System.Web.HttpRuntime.ProcessRequestNotificationPrivate(IIS7WorkerRequest)   wr,HttpContext context)+731

即使我实现了例如IAuthenticationFilter接口,无论如何都会抛出相同的异常。

有人有类似的例外吗?我无法在WebAPI中找到更多相关信息。

1 个答案:

答案 0 :(得分:40)

解决:问题是过滤器注册的地方。在MVC中,您将在FilterConfing类中注册过滤器,但在WebAPI中,您正在使用WebApiConfig类的Register方法执行此操作:

config.Filters.Add(new AuthAttribute());

现在一切正常。