【问题标题】:WCF serviceAuthorizationManager not being invokedWCF serviceAuthorizationManager 未被调用
【发布时间】:2015-09-04 02:36:02
【问题描述】:

尝试将 API 密钥授权添加到托管在 IIS 7 上的现有 WCF 服务

按照 Ron Jacob 的教程创建派生自 ServiceAuthorizationManager 的类。

它没有被调用。

如果我的理解有误,我希望我所要做的就是正确地创建类并在 Web.Config 中引用它。

此时我的测试网络客户端应该停止从服务获取数据,直到客户端被更改为处理 API 密钥流程。

但是,客户端仍然正确地使用合同,并且没有生成我放置在 ServiceAuthorizationManager 类中的 Eventlog 消息。

我以为一定是我创建的行为节点 在 web.config 中,但我已经手动和使用 Visual Studio 配置编辑器工具创建了它,这两个条目都不起作用。

我相信 web config serviceAuthorization 节点是正确的,因为它正确引用了授权类的 Namespace.Class,并且我已经仔细检查了 Webservice 的 bin 目录中的程序集是 CouponParkingWCF.dll。

类代码是:

namespace CouponParkingWCF
{

public class APIKeyAuthorization:ServiceAuthorizationManager
{
    public const string APIKEY = "ApiKey";
    public const string APIKEYLIST = "APIKeyList";


    public string GetAPIKey(OperationContext operationContext)
 {
    // Get the request message
     ClsLogger.WriteInfoLog("InsideGetAPIKey");
     var request = operationContext.RequestContext.RequestMessage;

    // Get the HTTP Request
     var requestProp = (HttpRequestMessageProperty)request.Properties[HttpRequestMessageProperty.Name];

     // Get the query string
    NameValueCollection queryParams = HttpUtility.ParseQueryString(requestProp.QueryString);

    // Return the API key (if present, null if not)
    return queryParams[APIKEY];
}

 public List<Guid> APIKeys
 {
     get
     {
         // Get from the cache
         // Could also use AppFabric cache for scalability
         var keys = HttpContext.Current.Cache[APIKEYLIST] as List<Guid>;

        if (keys == null)
            keys = PopulateAPIKeys();

       return keys;
    }
}

    private List<Guid> PopulateAPIKeys()
    {
        Dt dt = new Dt();
        List<Guid> keyList = dt.GetApiKeys();
        return keyList;
    }
     public bool IsValidAPIKey(OperationContext operationContext)
{
     // if verification is disabled, return true
    //if (Global.APIKeyVerification == false)
    //    return true;
   ClsLogger.WriteInfoLog("InsideIsValidAPIKey");
         //return true;
    string key = GetAPIKey(operationContext);

    Guid apiKey;

    // Convert the string into a Guid and validate it
    if (Guid.TryParse(key, out apiKey) && APIKeys.Contains(apiKey))
    {
        return true;
    }
         // Send back an HTML reply
         CreateErrorReply(operationContext, key);
         return false;
}

    private void CreateErrorReply(OperationContext operationContext, string key)
    {
        ClsLogger.WriteErrorLog("We have an Authorization Error. Oh Dear.");
    }

    protected override bool CheckAccessCore(OperationContext operationContext)
 {
    return IsValidAPIKey(operationContext);
 }
}
}

网络配置行为节点是:

<behaviors>
  <endpointBehaviors>
    <behavior name="RestJSONEndpointBehavior">
      <webHttp helpEnabled="false" defaultBodyStyle="Bare" defaultOutgoingResponseFormat="Json" />
    </behavior>
    <behavior name="RestXMLEndpointBehavior">
      <webHttp helpEnabled="false" defaultOutgoingResponseFormat="Xml" />
    </behavior>
  </endpointBehaviors>
  <serviceBehaviors>
    <behavior name="">
      <serviceAuthorization serviceAuthorizationManagerType="CouponParkingWCF.APIKeyAuthorization, CouponParkingWCF, Version=1.0.0.1, Culture=neutral, PublicKeyToken=null" />
    </behavior>
    <behavior name="wsdl">
      <serviceMetadata httpGetEnabled="false" httpsGetEnabled="false" />
      <serviceDebug includeExceptionDetailInFaults="true" />
    </behavior>
  </serviceBehaviors>
</behaviors>

希望有人能发现我做错了什么。

谢谢

鲍勃

【问题讨论】:

    标签: wcf


    【解决方案1】:

    问题是我将 serviceAuthorization 节点放在了它自己的行为节点中。 它应该进入现有的“wsdl”节点

     <serviceBehaviors>
        <behavior name="wsdl">
           <serviceAuthorization serviceAuthorizationManagerType="CouponParkingWCF.APIKeyAuthorization, CouponParkingWCF, Version=1.0.0.1, Culture=neutral, PublicKeyToken=null" />
          <serviceMetadata httpGetEnabled="true" httpsGetEnabled="true" />
          <serviceDebug includeExceptionDetailInFaults="true" />
        </behavior>
      </serviceBehaviors>
    

    这让 API KEY 正常工作,但我们需要让它为 GET 和 POST 工作。 Ron 的示例显示了使用查询字符串,该字符串适用于 GET,但不适用于 POST。 所以我们开始将 API Key 放入头部。 WCF密钥提取代码为:

     public string GetAPIKey(OperationContext operationContext)
        {
            try
            {
                var request = operationContext.RequestContext.RequestMessage;
                var requestProp = (HttpRequestMessageProperty)request.Properties[HttpRequestMessageProperty.Name];
    
                string key = requestProp.Headers["ApiKey"];
                return key;
            }
            catch (Exception exception)
            {
                ClsLogger.WriteErrorLog("GetAPIKey " + exception.Message); 
                throw;
            }
        }
    

    【讨论】:

      猜你喜欢
      • 2013-07-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-09-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多