您将如何在WCF数据服务中实现API密钥?

Rus*_*sby 5 c# service ado.net wcf odata

有没有办法在URL中使用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);
    }
} 
Run Code Online (Sandbox Code Playgroud)

...这有效,但它并不完美,因为您无法通过添加服务参考资源管理器获取元数据并发现服务.我可以检查$元数据是否在网址中,但它似乎是一个黑客.有没有更好的办法?

Dar*_*ler 5

我建议使用授权头传递apiKey而不是在查询字符串中传递它.这就是它的用途,它有助于将api密钥保留在日志文件之外.

我认为检查网址中是否存在'$ metadata'并没有什么问题.您正在编写服务器端代码,并且服务器拥有URI空间,因此根据请求URL中的文本做出决策是服务器的全部内容.你可以用类似的东西,

  if (requestUrl.Segments.Last().Replace('/','') != '$metadata') 
Run Code Online (Sandbox Code Playgroud)

而不是搜索整个uri字符串,如果它让它感觉不那么icky!