2016-08-22 66 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和祕密爲api返回一個令牌,此令牌用於授權其他請求。該令牌也將有一個過期,並有方法來獲取刷新令牌。

因此,你必須接受一個關於你必須爲你的api執行多少安全性的調用。你可以有一個類似的方法,你的客戶首先通過提供客戶端ID和祕密(這應該是一個祕密)來請求安全令牌。你可以檢查這個ID和祕密針對你的商店(可能是數據庫),如果通過了驗證,你可以發回一個令牌,你可以使用[Authroize]屬性或自定義驗證進行authroize。

如何創建令牌應該是IMO的另一個討論。這裏提到了簡單的方法,例如:how to generate a unique token which expires after 24 hours?。還有其他標準的生成令牌JWT/OAuth令牌的方式。

編輯 作爲一個簡單的方法(沒有采取太多的安全性方面考慮)將是:

  • 創建一個應用程序的祕密(可能是一個GUID值)
  • 雖然發送請求,獲取當前時間戳並加密(使用自己的加密和解密邏輯)具有應用祕密的時間戳。讓我們稱之爲該加密值作爲「令牌」
  • 傳入您的請求頭中的令牌(可自定義標題,比方說, X-MY-AUTH)
  • 在API中,有一個自定義授權過濾
  • 在自定義過濾器,覆蓋OnAuthroizeCore方法,從請求頭
  • 得到 令牌使用相同的應用程序祕密解密令牌,你會得到 時間戳從客戶
  • 如果解密是好的,那麼我們是通過發送第一步/或令牌通過第一步
  • Additionaly,檢查令牌解密當前時間 和時間之間的差異是否大於5(*你可以有你 自己的過期值)
  • 如果差大於你的有效期限多,返回false這 會拋出異常擅自返回給客戶端(做同樣的,如果令牌不能解密
  • 到期支票處理如果有人入侵您的請求 令牌,然後以後使用它的情況。在他 使用該令牌的期限屆滿後的情況下,這將拋出未經授權

考慮以上邏輯和整個描述只是作爲一個「思考的食糧」,沒有適當的研究和理解,不要使用它。我的想法是給出一些關於應用程序認證的基本概念,直到有人真的擅長這一點在本文中寫出一篇非常好的文章

+1

您不應該將「祕密」與請求一起發送。這否定了「祕密」的全部目的。發佈該祕密以允許您加密或以其他方式保護您對API的請求,例如生成HMAC以防止重播攻擊。 –

+0

@ChrisPratt - 非常真實,我只是想讓OP非常簡單,假設他會對此做進一步的研究;我會更新我的答案/請隨時更新。感謝您指出這一點。 – Developer

相關問題