2016-09-27 6 views
10

WebAPIを実行しようとすると、認証用のカスタムフィルタを作成しようとしています。溶液:System.Web.Mvc.IAuthorizationFilter、 System.Web.Mvc.IActionFilter、System.Web.Mvc.IResultFilter、 :例外:WebAPIでカスタムフィルタを実装するときに、指定されたフィルタで次のフィルタインターフェイスを実装する必要があります。2

所与のフィルタ・インスタンスは、以下 フィルタインターフェースの一つ以上を実装する必要がありますSystem.Web.Mvc.IExceptionFilter、 System.Web.Mvc.Filters.IAuthenticationFilter。

エラーがに、FilterConfigクラスで発生します。私は、フィルタにAuthAttributeを追加しようとしているラインで

public class FilterConfig 
{ 
    public static void RegisterGlobalFilters(GlobalFilterCollection filters) 
    { 
     filters.Add(new HandleErrorAttribute()); 
     filters.Add(new 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.Gl obalFilterCollection.AddInternal(オブジェクトフィルタ、 Nullable`1順)26
System.Web.Mvc.GlobalFilterCollection.Add(オブジェクトフィルタ)Cで31
Examino.API.FilterConfig.RegisterGlobalFilters(GlobalFilterCollection フィルター):\ examino \ SRC \ Examino.API \ App_Start \ FilterConfig.cs:12
Examino.API.WebApiApplication.Application_Start() でC:\ examino \ SRC \ Examino.API \ Global.asax.cs:22

[HttpException(0x80004005)]:指定されたフィルタインスタンスは、 System.Web.Mvc.IAuthorizationFilter、System.Web.Mvのいずれか1つ以上を に実装する必要があります。 c.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 []ハンドラのIntPtr AppContextを、コンテキストのHttpContext )+172
System.Web.HttpApplicationFactory.GetSpecialApplicationInstance(IntPtr appContext、HttpContextコンテキスト)+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コンテキスト)539
システム.Web.HttpRuntime.EnsureFirstRequestInit(HttpContextコンテキスト) +125 System.Web.HttpRuntime.ProcessRequestNotificationPrivate(IIS7WorkerRe私は例IAuthenticationFilterインターフェイス同じ例外のために実装する場合であってもクエスト WR、のHttpContextコンテキスト)731

はとにかくスローされます。

誰かに同様の例外がありましたか?私はこれについてWebAPIで何かを見つけることができませんでした。

答えて

21

解決済み:問題はフィルタの登録場所でした。 MVCでは、FilterConfingクラスでフィルタを登録しますが、WebAPIの中で、あなたはこのようなWebApiConfigクラスの登録方法でこれをやっている:

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

すべてが機能するようになりました。

関連する問題