Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/292.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/wcf/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 您将如何在WCF数据服务中实现API密钥?_C#_Wcf_Service_Ado.net_Odata - Fatal编程技术网

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

C# 您将如何在WCF数据服务中实现API密钥?,c#,wcf,service,ado.net,odata,C#,Wcf,Service,Ado.net,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

有没有一种方法需要在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);
    }
} 

…这可以工作,但并不完美,因为您无法通过添加服务引用资源管理器获取元数据并发现服务。我可以检查url中是否有$metadata,但这似乎是一个黑客行为。有更好的方法吗?

您可以检查请求类型,让wsdl调用在不使用api键的情况下完成


我不确定您的api目标是什么,但您可以使用客户端证书。

我建议使用授权标头来传递api密钥,而不是在查询字符串中传递它。这就是它的用途,它有助于将api密钥从日志文件中删除

我认为检查url中是否存在“$metadata”并没有什么问题。您正在编写服务器端代码,而服务器拥有URI空间,因此基于请求url中的文本做出决策是服务器的全部工作。 你可以用这样的东西

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

而不是搜索整个uri字符串,如果它让它感觉不那么讨厌的话

中介绍的技术即使在WCF数据服务中也能很好地工作。您可以创建
ServiceAuthorizationManager
(请参阅)的自定义子类,重写
CheckAccessCore()
,并在web.config中注册它

我通过在请求的HTTP头中传递一个密钥来实现它。传递给
CheckAccessCore
OperationContext
无法获取HTTP请求头,但您可以通过
HttpContext.Current.Request.headers
获取它们。然后,您可以从该集合中获取适当的标头,并根据需要进行检查

以下是在web.config中进行的必要注册:

<system.serviceModel>
  <behaviors>
      <serviceBehaviors>
          <behavior>
              <serviceAuthorization serviceAuthorizationManagerType="FullyQualifiedTypeNameHere, ProjectNameHere" />
          </behavior>
      </serviceBehaviors>
  </behaviors>
如果除ADO.NET服务外还运行普通WCF服务,请在服务实现的上方添加以下内容:

[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Required)]

然后您可以获得
HttpContext.Current.Request.Headers
以及
HttpRequest
类提供的所有其他内容。

您所说的请求类型是什么意思?$metadata端点不是WSDL,而是CSDL,不是吗?我在MSDN论坛上得到了类似的答案。我真不敢相信没有更好的办法了。这看起来像一个黑客,但看起来我将不得不走这条路。谢谢。这对这里描述的缓存机制有效吗:这里的问题是,无论客户端请求什么格式,错误都会以XML形式返回。
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Required)]