未调用WCF serviceAuthorizationManager

时间:2015-09-04 02:36:02

标签: wcf

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

遵循Ron Jacob关于创建从ServiceAuthorizationManager派生的类的教程。

没有被调用。

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

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

然而,客户端仍然正确地使用了合同,并且没有生成我放在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);
 }
}
}

Web配置行为节点是:

<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>
希望有人能发现我做错了什么。

由于

鲍勃

1 个答案:

答案 0 :(得分:0)

问题在于我将serviceAuthorization节点放在其自己的行为节点中。 它应该进入现有的&#34; wsdl&#34;节点

 <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;
        }
    }