我正在尝试构建自定义过滤器以进行身份验证,但是当我尝试运行我的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中找到更多相关信息。
答案 0 :(得分:40)
解决:问题是过滤器注册的地方。在MVC中,您将在FilterConfing
类中注册过滤器,但在WebAPI中,您正在使用WebApiConfig
类的Register方法执行此操作:
config.Filters.Add(new AuthAttribute());
现在一切正常。