有没有办法要求 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);
    }
} 

...这可行,但并不完美,因为您无法通过“添加服务引用”资源管理器获取元数据并发现服务。我可以检查 $metadata 是否在 url 中,但这看起来像是一个 hack。有没有更好的办法?

有帮助吗?

解决方案

我建议使用授权报头传递apiKey而不是传递它在查询串中的。这就是它是有它帮助的保持API密钥了日志文件。

我不觉得有什么真的错了与检查“$元数据”的在URL中存在。你正在写的服务器端代码和服务器拥有的URI空间,所以使得基于请求URL文本决定是服务器的全部。 你可以使用像,

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

而不是搜索整个URI字符串,如果这能让它感觉不到恶心!

其他提示

看起来像中介绍的技术 这个视频 即使在 WCF 数据服务中也能正常工作。您创建一个自定义子类 ServiceAuthorizationManager (看 微软软件定义网络), 覆盖 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; HttpContext.Current 在 IIS 中运行时为 null(但有趣的是在调试时不是)。相反,使用 WebOperationContext.Current.IncomingRequest.Headers 按照 这个问题.

更新2: HttpContext.Current 仅当您未在 ASP.NET 兼容模式下运行 WCF 时,才为 null。您可以通过将以下行添加到应用程序级别的 web.config 中来打开此功能 system.serviceModel 节点:

<serviceHostingEnvironment aspNetCompatibilityEnabled="true"/>

如果除了 ADO.NET 服务之外还运行着普通的 WCF 服务,还要在服务的实现上方添加此内容:

[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Required)]

然后你可以得到 HttpContext.Current.Request.Headers 以及由 HttpRequest 班级。

您可以检查请求的类型和让WSDL与呼叫出来的API密钥去。

我不知道您的API的目标是什么,但你可以使用客户端证书。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top