2016-08-22 6 views
-1

私は以下のようなコントローラアクションメソッドを使ってapi呼び出しを行っています。以下は、その作業コードです。 しかし私は自分のアプリケーションだけがアクセスできるようにwebapiを保護したいと思います。私はログイン資格情報 でソースを見たことがありますが、私の場合はログインユーザーがいない一般公開のウェブサイトです。 アプリケーションからの呼び出しにのみアクセスする必要があります。誰でも何ができるのかを教えてください。またはValidateReferrerを使用している私の現在のコードで十分ですか?コントローラで私のアプリだけがそれにアクセスできるようにmvc5 c#webapiを許可してください

[HttpGet] 
[ValidateReferrer] 
[ActionName("GetFind")] 
[CacheOutput(ClientTimeSpan = 300, ServerTimeSpan = 300)] 
public ApiQueryResponse GetFind(string query) 
{ 
    return _Worker.GetFind(query); 
} 

検証リファラーは、次の実装があります。ワーカークラスで

public override void OnAuthorization(AuthorizationContext filterContext) 
{ 
    if (filterContext.HttpContext == null) 
    { 
     throw new System.Web.HttpException("No Http context, request not allowed."); 
    } 
    else 
    { 
     if (filterContext.HttpContext.Request.UrlReferrer == null) 
     { 
      throw new System.Web.HttpException("Referrer information missing, request not allowed."); 
     } 
     else if (filterContext.HttpContext.Request.UrlReferrer.Host != filterContext.HttpContext.Request.Url.Host) 
     { 
      throw new System.Web.HttpException(string.Format("Possible cross site request forgery attack, request sent from another site: {0}", filterContext.HttpContext.Request.UrlReferrer.Host)); 
     } 
    } 
} 

public ApiQueryResponse GetFind(string query) 
{ 
    var results = GetResults(Settings.ApiKey, SetFindParameters(query), Resource);   
    return results; 
} 

private ApiQueryResponse GetResults(string apiKey, string parameterQuery, string Resource) 
{ 
    var results = new ApiQueryResponse(); 
    if (apiKey != null && !String.IsNullOrWhiteSpace(apiKey)) 
    { 
     using (var client = new HttpClient()) 
     { 
      client.DefaultRequestHeaders.Accept.Clear(); 
      client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); 
      var response = client.GetAsync(string.Format("{0}/{1}?{2}&key={3}", WebApiUrl, Resource, parameterQuery, apiKey)).Result; 
      if (response.IsSuccessStatusCode) 
      { 
       var responseBodyAsText = response.Content.ReadAsStringAsync().Result; 
       results = JsonConvert.DeserializeObject<ApiQueryResponse>(responseBodyAsText); 
      } 
     } 
    } 
    return results; 
} 

答えて

1

を再度、これはあなたがあなたの「アプリケーション」を認証する必要がありそうですユーザーではありません。 facebook/twitter/gmail apiをチェックすると、アプリケーションを認証するためのクライアントシークレットとクライアントIDがあります。しかし、依然として、このIDと秘密を使って行われた "Authorize"呼び出しと、apiがトークンを返す秘密があり、このトークンは以後、他の要求を許可するために使用されます。このトークンには有効期限があり、リフレッシュトークンを取得するメソッドがあります。

このように、あなたはあなたのAPIのために実装する必要があるセキュリティの量を求める必要があります。クライアントIDとシークレット(本当に秘密にする必要があります)を提供することで、クライアントが最初にセキュリティトークンを要求するのと同様のアプローチをとることができます。このIDとシークレットを店舗(データベースの可能性があります)と照合することができ、検証に合格した場合は、[Authroize]属性またはカスタム検証を使用して自動化できるトークンを返すことができます。

トークンを作成するには別のディスカッションIMOが必要です。簡単なアプローチは、例えば、how to generate a unique token which expires after 24 hours?についてここで言及される。トークンJWT/OAuthトークンを生成する他の標準的な方法があります。単純なアプローチとして

EDIT考慮に多くのセキュリティ面を服用していない)は次のようになります。リクエストを送信しながら

  • をアプリシークレットを作成します(GUID値であってもよいです)、現在のタイムスタンプを取得して(あなたの 自身の暗号化と復号化ロジックを持っている)タイムスタンプとアプリの秘密を暗号化します。「トークン」として値を暗号化し、コール
  • は、カスタムフィルタ
  • を承認する必要があり、(たとえば、 X-MY-AUTHカスタムヘッダであってもよい)あなたのリクエストヘッダにAPIで
  • をトークンを渡すことができますOnAuthroizeCoreメソッドオーバーライドされ、カスタムフィルタでは、同じアプリの秘密を使用してトークンを復号化リクエストヘッダ
  • から トークンを取得し、あなたは、復号化に問題がない場合は
  • は、その後、我々は通過しているクライアントから送信され タイムスタンプを取得します最初のステップ/または トークンが最初のステップを通過しました
  • Additionaly、(*あなた 自身の時間切れ値を持つことができます)
  • 違いは、あなたの有効期限の制限を超えている場合は、falseを返す現在の時刻 の違いかどうかを確認し、トークンから復号化された時間が5つ以上ありますこれ 有効期限のチェックは、誰かがリクエストからご トークンをハッキングして、後でそれを使用してシナリオを処理することです
  • (トークンがを解読するのに失敗した場合に同じことを行う)に戻って、クライアントへの不正な例外をスローします。彼 があなたの満了後トークンを使用している場合場合には、これは単に「思考のための食品」として上記の論理と全体の説明を検討し、適切な研究と理解せずにそれを使用しない不正

をスローしていました。私のアイデアは、本当に良い人がこの投稿に本当に素敵な記事を書くまで、アプリケーション認証についての基本的なアイデアを与えることでした。

+1

「秘密」を要求とともに送信しないでください。それは「秘密」の目的をすべて否定します。シークレットは、リプレイ攻撃を防ぐためにHMACを生成するなど、APIに対する要求を暗号化または保護するために発行されます。 –

+0

@ChrisPratt - 私はちょうど彼がこれについてさらに研究をすると仮定して、OPのためにそれを本当に簡単にするようにしていました。私は私の答えを更新する/更新する気軽にしてください。これを指摘していただきありがとうございます。 – Developer

関連する問題