2016-08-05 16 views
2

ASP.NET MVC 5 Webサイト/アプリケーションのWeb APIコントロール用のカスタムフィルタを作成して、データベースに格納されている特定のトークンのリクエストヘッダーをチェックしようとしています。私が見つけたほとんどの例にはユーザーの資格情報が含まれていて、ユーザーはIDを使用して認証されていました。正確には私が探しているものではありません。Web APIカスタム認証フィルタ

これは、私が見つけた、現在遂行中のtutorialです。

ウェブAPIは「外部」HTTPコールのみを処理する必要があります。ウェブサイト側には現在、独自のコントローラがあります(ただし、変更される可能性があります)。

このフィルタは、可能であれば、既に存在するアイデンティティ2システムとインタフェースする必要があります。

私は、ユーザー資格情報を送信し、ユーザーにトークンを割り当ててから、そのトークンを使用して要求を認証したいと考えています。トークンに基づいてリクエストをフィルタリングする方法や、OwinのIDとトークン管理を使用する必要があるかどうかを確認する方法はありますか?私はモバイルクライアントを使用しています(現在はiOS、Androidを含む予定です)。私が参照できる例やチュートリアルはありますか?

トークンは現在、英数字と記号のランダムな組み合わせです。

ありがとうございます。

P.S.必要に応じてコードスニペットやものを投稿することができます。

編集:HTTPRequestは、データベース/システム内にトークンが含まれているかどうかによってフィルタリングされます。トークンが含まれているか、私たちのシステムに存在しないリクエストは、不正なエラー(401?)を受け取ります。

+0

トークンはHTTPリクエストヘッダーにありますか? – Botonomous

+0

はい、トークンは要求ヘッダーにあります。 – beowulf

+0

トークンに基づいて要求をフィルタリングすることはどういう意味ですか?すべてのHTTPReqeustにトークンが含まれるわけではありませんか、トークンを持っているときにのみリクエストをフィルタリングする必要がありますか? – Botonomous

答えて

5

すべてのリクエストにユーザー名とパスワードを送信するのは良いとは思っていません。パスワードは、リクエストごとにユーザー名とパスワードを送信しないためです。

public class AuthenticationFilter : AuthorizationFilterAttribute 
    { 
     /// <summary> 
     /// read requested header and validated 
     /// </summary> 
     /// <param name="actionContext"></param> 
     public override void OnAuthorization(HttpActionContext actionContext) 
     { 
      var identity = FetchFromHeader(actionContext); 

      if(identity != null) 
      { 
       var securityService = actionContext.ControllerContext.Configuration.DependencyResolver.GetService(typeof(ILoginService)) as ILoginService; 
       if (securityService.TokenAuthentication(identity)) 
       { 
        CurrentThread.SetPrincipal(new GenericPrincipal(new GenericIdentity(identity), null), null, null); 
       } 
       else 
       { 
        actionContext.Response = new HttpResponseMessage(HttpStatusCode.Unauthorized); 
        return; 
       } 
      } 
      else 
      { 
       actionContext.Response = new HttpResponseMessage(HttpStatusCode.BadRequest); 
       return; 
      } 
      base.OnAuthorization(actionContext); 
     } 

     /// <summary> 
     /// retrive header detail from the request 
     /// </summary> 
     /// <param name="actionContext"></param> 
     /// <returns></returns> 
     private string FetchFromHeader(HttpActionContext actionContext) 
     { 
      string requestToken = null; 

      var authRequest = actionContext.Request.Headers.Authorization; 
      if (authRequest != null && !string.IsNullOrEmpty(authRequest.Scheme) && authRequest.Scheme == "Basic") 
       requestToken = authRequest.Parameter; 

      return requestToken; 
     } 
    } 
2

このフィルタユニットをプロパティ(プロパティインジェクション)を介して注入することで、このフィルタユニットをテスト可能にすることができます。カスタム属性の場合、コンストラクタを介して依存関係を渡す必要はありません。私たちは属性を使いやすくするために を使います。 @Rajはすでに始まっ何を書き換えるために、それは次のようになります。

public class AuthenticationFilter : AuthorizationFilterAttribute 
    { 
     [Dependency] 
     public ILoginService LoginService { get; set; } 

     /// <summary> 
     /// read requested header and validated 
     /// </summary> 
     /// <param name="actionContext"></param> 
     public override void OnAuthorization(HttpActionContext actionContext) 
     { 
      var identity = FetchFromHeader(actionContext); 

      if (identity != null) 
      { 
       if (LoginService.TokenAuthentication(identity)) 
       { 
        CurrentThread.SetPrincipal(new GenericPrincipal(new GenericIdentity(identity), null), null, null); 

        //IPrincipal principal = new GenericPrincipal(new GenericIdentity(identity), new string[] { "myRole" }); 
        //Thread.CurrentPrincipal = principal; 
        //HttpContext.Current.User = principal;    
       } 
       else 
       { 
        actionContext.Response = new HttpResponseMessage(HttpStatusCode.Unauthorized); 
        return; 
       } 
      } 
      else 
      { 
       actionContext.Response = new HttpResponseMessage(HttpStatusCode.BadRequest); 
       return; 
      } 
      base.OnAuthorization(actionContext); 
     } 

     /// <summary> 
     /// retrive header detail from the request 
     /// </summary> 
     /// <param name="actionContext"></param> 
     /// <returns></returns> 
     private string FetchFromHeader(HttpActionContext actionContext) 
     { 
      string requestToken = null; 

      var authRequest = actionContext.Request.Headers.Authorization; 
      if (authRequest != null && !string.IsNullOrEmpty(authRequest.Scheme) && authRequest.Scheme == "Basic") 
       requestToken = authRequest.Parameter; 

      return requestToken; 
     } 
    } 
-1

を回答していただきありがとうございますが、いくつかの実験の後、私は、ベアラトークンでOAuthの2認証を使用するように全体のAPIを作り直し。それは私の問題をフィルタで解決しました。