I am trying to build my custom filter for authentication, but I am running on this problem when I try to run my WebAPI solution:
The given filter instance must implement one or more of the following filter interfaces: System.Web.Mvc.IAuthorizationFilter, System.Web.Mvc.IActionFilter, System.Web.Mvc.IResultFilter, System.Web.Mvc.IExceptionFilter, System.Web.Mvc.Filters.IAuthenticationFilter.
The error occurs in FilterConfig class:
public class FilterConfig
{
public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
filters.Add(new HandleErrorAttribute());
filters.Add(new AuthAttribute());
}
}
In the line where I am trying to add AuthAttribute to filters.
This is whole AuthAttribute class:
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
}
}
}
As you can see it inherits from AuthorizeAttribute
class.
Here is a stack trace:
[InvalidOperationException: The given filter instance must implement one or more of the following filter interfaces: 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(Object instance) +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 filters) in 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): The given filter instance must implement one or more of the following filter interfaces: 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 context, HttpApplication app) +540
System.Web.HttpApplication.RegisterEventSubscriptionsWithIIS(IntPtr appContext, HttpContext context, MethodInfo[] handlers) +186
System.Web.HttpApplication.InitSpecial(HttpApplicationState state, 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): The given filter instance must implement one or more of the following filter interfaces: 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
Even if I implement for example IAuthenticationFilter
interface same exception is thrown anyhow.
Did someone had a similar exception? I was unable to find something more about this in WebAPI.
Solved: The problem was place of registration of Filter. In MVC you would register filters in FilterConfing
class, but in WebAPI you are doing this in Register method of WebApiConfig
class like this:
config.Filters.Add(new AuthAttribute());
Everything works now.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With