2016-09-27 27 views
10

'daki özel filtreyi uygularken aşağıdaki filtre arabirimlerinden birini veya daha fazlasını gerçekleştirmelidir Özel filtreyi kimlik doğrulaması için oluşturmaya çalışıyorum, ancak WebAPI'mı çalıştırmaya çalıştığımda bu sorunla karşılaşıyorum çözelti:İstisna: Verilen filtre WebAPI 2

belirli bir filtre, örneğin bir ya da aşağıdaki filtre arabirimlerinin daha uygulamalıdır

: System.Web.Mvc.IAuthorizationFilter, System.Web.Mvc.IActionFilter, System.Web.Mvc.IResultFilter, System.Web.Mvc.IExceptionFilter, System.Web.Mvc.Filters.IAuthenticationFilter.

hata FilterConfig sınıfında oluşur: Ben filtrelere AuthAttribute eklemek çalışıyorum doğrultusunda

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

.

budur bütün AuthAttribute sınıfı:

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

bunu AuthorizeAttribute sınıfından devralan görebileceğiniz gibi.

[ınvalidoperationexception: Burada

yığıtı belirli bir filtre örneği, aşağıdaki filtre arabirimleri bir ya da daha fazla uygulamak gerekir: 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 (Obje örneği) 403
System.Web.Mvc.Gl obalFilterCollection.AddInternal (Nesne filtresi, Nullable`1 sırası) + 26
System.Web.Mvc.GlobalFilterCollection.Add (Obje filtre) C +31
Examino.API.FilterConfig.RegisterGlobalFilters (GlobalFilterCollection filtreler): \ examino \ src \ Examino.API \ App_Start \ FilterConfig.cs: C 12
Examino.API.WebApiApplication.Application_Start(): \ examino \ src \ Examino.API \ Global.asax.cs: 22

[HttpException (0x80004005): Verilen filtre örneği, aşağıdaki filtre arabirimlerinden birini veya daha fazlasını gerçekleştirmelidir: System.Web.Mvc.IAuthorizationFilter, System.Web.Mv c.IActionFilter, System.Web.Mvc.IResultFilter, System.Web.Mvc.IExceptionFilter, System.Web.Mvc.Filters.IAuthenticationFilter.]
System.Web.HttpApplicationFactory.EnsureAppStartCalledForIntegratedMode (HttpContext kapsamı, HttpApplication uygulama) 540
System.Web.HttpApplication.RegisterEventSubscriptionsWithIIS (ıntptr appcontext, HttpContext bağlam, MethodInfo [] yükleyiciler) 186
System.Web.HttpApplication.InitSpecial (HttpApplicationState durumu, MethodInfo [] yükleyiciler, ıntptr appcontext, HttpContext bağlam) +172
System.Web.HttpApplicationFactory.GetSpecialApplicationInstance (IntPtr appContext, HttpContext içeriği) +402
System.Web.Hosting.PipelineRuntime.InitializeApplication (ıntptr appcontext) 343

[HttpException (0x80004005): belirli bir filtre örneği, aşağıdaki filtre arabirimleri bir ya da daha fazla uygulamak gerekir: 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 bağlamı) 539
Sistemi .Web.HttpRuntime.EnsureFirstRequestInit (HttpContext içeriği) +125 System.Web.HttpRuntime.ProcessRequestNotificationPrivate (IIS7WorkerRe) Ben örnek IAuthenticationFilter arayüzü aynı istisna için uygulamak bile arayışı wr, HttpContext bağlam) +731

nasıl olsa atılır.

Birisi benzer bir özel durum muydu? WebAPI'da bu konuda daha fazla şey bulamadım.

cevap

21

Çözüldü: Sorun, Filtre kaydının yapıldığı yerdi. MVC size FilterConfing sınıfta filtreleri kayıt altına alacak, ancak WebAPI içinde böyle WebApiConfig sınıfının Kayıt yönteminde yapıyoruz:

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

Şimdi herşey çalışıyor.