2010-03-20 63 views
4

有沒有一種方法可以要求URL中的API密鑰/或其他方式將服務傳遞給私鑰以授予對數據的訪問權限?如何在WCF數據服務中實現API密鑰?

我現在有這個權利......

using System; 
using System.Data.Services; 
using System.Data.Services.Common; 
using System.Collections.Generic; 
using System.Linq; 
using System.ServiceModel.Web; 
using Numina.Framework; 
using System.Web; 
using System.Configuration; 

[System.ServiceModel.ServiceBehavior(IncludeExceptionDetailInFaults = true)] 
public class odata : DataService { 


    public static void InitializeService(DataServiceConfiguration config) { 

     config.SetEntitySetAccessRule("*", EntitySetRights.AllRead); 
     //config.SetServiceOperationAccessRule("*", ServiceOperationRights.All); 
     config.DataServiceBehavior.MaxProtocolVersion = DataServiceProtocolVersion.V2; 
    } 

    protected override void OnStartProcessingRequest(ProcessRequestArgs args) { 

     HttpRequest Request = HttpContext.Current.Request; 
     if(Request["apikey"] != ConfigurationManager.AppSettings["ApiKey"]) 
      throw new DataServiceException("ApiKey needed"); 

     base.OnStartProcessingRequest(args); 
    } 
} 

...這工作,但因爲你不能在元數據獲取,發現通過添加服務引用探險服務它並不完美。我可以檢查$ metadata是否在url中,但它看起來像一個黑客。有沒有更好的辦法?

+0

這個工作與緩存機械描述在這裏:http://www.hanselman.com/blog/CreatingAnODataAPIForStackOverflowIncludingXMLAndJSONIn30Minutes.aspx – friism 2010-09-05 10:56:33

回答

5

我會建議使用授權標頭來傳遞apiKey而不是將它傳遞到查詢字符串中。這就是它的目的,它有助於保持日誌文件中的api密鑰。

我不認爲檢查URL中是否存在'$ metadata'是沒有什麼錯誤的。您正在編寫服務器端代碼,並且服務器擁有URI空間,因此根據請求url中的文本做出決定就是服務器的全部內容。 你可以使用像,

if (requestUrl.Segments.Last().Replace('/','') != '$metadata') 

,而不是搜索整個URI字符串,如果它使得它覺得少噁心!

+0

我在MSDN論壇上有類似的答案。我不相信沒有更好的辦法。這看起來像一個黑客,但它看起來像我將不得不這樣。謝謝。 – 2010-03-20 19:30:08

0

您可以檢查請求類型並讓wsdl調用通過api密鑰。

我不確定你的api目標是什麼,但你可以使用客戶端證書。

+1

你是什麼意思的請求類型? $元數據端點不是WSDL,它是CSDL,不是? – 2010-03-20 12:36:57

1

看起來像this video中介紹的技術即使在WCF數據服務中也能很好地工作。您創建ServiceAuthorizationManager的自定義子類(請參閱MSDN),覆蓋CheckAccessCore(),並將其註冊到web.config中。

我通過在請求的HTTP頭中傳遞一個鍵來得到它的工作。 OperationContext傳遞給CheckAccessCore不會讓您獲取HTTP請求標頭 ,但您可以通過 HttpContext.Current.Request.Headers獲取它們。然後,您可以從該集合中獲取適當的標題,然後檢查它是否需要。

這裏是web.config中的必要的登記:

<system.serviceModel> 
    <behaviors> 
     <serviceBehaviors> 
      <behavior> 
       <serviceAuthorization serviceAuthorizationManagerType="FullyQualifiedTypeNameHere, ProjectNameHere" /> 
      </behavior> 
     </serviceBehaviors> 
    </behaviors> 

更新:我錯了大約能夠得到頭出來的HttpContext.Current.Request.Headers;在IIS中運行時HttpContext.Current爲空(但有趣的是不在調試時)。相反,根據this question使用WebOperationContext.Current.IncomingRequest.Headers

UPDATE 2:HttpContext.Current僅當您在ASP.NET兼容模式下運行WCF時才爲空。

<serviceHostingEnvironment aspNetCompatibilityEnabled="true"/> 

而且添加該服務的實現上面的,如果你有除了運行香草WCF服務:您可以通過在system.serviceModel節點添加以下行的web.config在應用程序級別啓用該選項到ADO。NET服務:

[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Required)] 

然後你就可以得到HttpContext.Current.Request.Headers等全部由HttpRequest類提供了其他的東西。

+0

這裏的問題是無論客戶請求什麼格式,在所有情況下都會以XML的形式返回錯誤。 – Monstieur 2013-02-20 05:48:09