WCF自定义JSONP绑定和httpsTransport

时间:2009-09-17 17:39:03

标签: c# wcf rest iis-6

我的问题围绕用于响应JSONP的IIS的WCF REST服务。我参加了这个解决方案中的课程:http://msdn.microsoft.com/en-us/library/cc716898.aspx并将它们添加到我的解决方案中。使用httpTransport模拟我的开发人员工作站上的工作正常,但当我尝试升级到开发服务器时遇到了一些安全问题。使用下面的配置和App Pool身份用户解决了这些问题。我还配置IIS元数据库文件仅用于NTLM身份验证(我们正在使用IIS 6,但很快就会是IIS 7,需要同时使用它们),因为我无权创建SPN。我相信当前的配置解决了我的安全问题但在此过程中我的JSONP响应被降级为regualar JSON ,这就是问题所在。以下是相关配置:

    <services>
        <service name="IS.Core.Infrastructure.RESTRouter.Transactions" behaviorConfiguration="">
            <endpoint address="" behaviorConfiguration="webHttp" binding="customBinding"
              bindingConfiguration="jsonpBinding" contract="IS.Core.Infrastructure.RESTRouter.ITransactions">
            </endpoint>
        </service>

        <service name="IS.Core.Infrastructure.RESTRouter.Queue" behaviorConfiguration="">
            <endpoint address="" behaviorConfiguration="webHttp"  binding="customBinding"
                bindingConfiguration="jsonpBinding" contract="IS.Core.Infrastructure.RESTRouter.IQueue" />
        </service>
    </services>

    <behaviors>
        <endpointBehaviors>
            <behavior name="webHttp">
                <webHttp />
            </behavior>
        </endpointBehaviors>
    </behaviors>

    <bindings>
        <customBinding>
            <binding name="jsonpBinding">
                <jsonpMessageEncoding />
                <httpsTransport
                      manualAddressing="true"
                      authenticationScheme="Ntlm" />
            </binding>
        </customBinding>
    </bindings>

    <extensions>
        <bindingElementExtensions>
            <add name="jsonpMessageEncoding"
              type="IS.Core.Infrastructure.RESTRouter.JsonpBindingExtension, RESTRouter, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
        </bindingElementExtensions>
    </extensions>

以下是接口方法定义之一:

    [OperationContract]
    [WebGet(UriTemplate = "{ModelPath}/{ObjectTypeName}?callback={callback}", ResponseFormat = WebMessageFormat.Json)]
    [JSONPBehavior(callback = "callback")]
    JSONPXml NewObject(string ModelPath, string ObjectTypeName, string callback);

以下是其实施:

    [OperationBehavior(Impersonation = ImpersonationOption.Allowed)]
    public JSONPXml NewObject(string ModelPath, string ObjectTypeName, string callback) {

        int val = getEmployeeIdByNTUsername(OperationContext.Current.ServiceSecurityContext.PrimaryIdentity.Name);

        JSONPXml jsp = null;
        EntityPluginReflectorClient client = null;
        try {
            client = new EntityPluginReflectorClient();
            string output = client.NewObject(ModelPath, ObjectTypeName);
            jsp = new JSONPXml() { xml = output };
        } catch (Exception e) {
            InfrastructureLog.WriteException(this, "NewObject", e);
            jsp = getExceptionResponse(e);
        }
        finally {
            client.Close();
        }
        return (jsp);
    }

这是数据合同:

[DataContract()]
public class JSONPXml {
    public JSONPXml() { }
    [DataMember]
    public string xml;
}

如果需要更多信息,请与我们联系。感谢您对此进行调查。

2 个答案:

答案 0 :(得分:1)

我不是100%肯定答案,但这里有一些东西可以帮助你缩小范围:

对于初学者,如果将ProtectionLevel显式设置为Sign或EncryptAndSign,则必须使用启用了安全性的绑定,否则将引发异常。如果您尝试通过http访问异常,这将开始抛出异常,这可以帮助您弄清楚您实际访问该服务的方式。

其次,由于您使用的是customBinding,因此您需要告诉它在绑定中需要哪种类型的安全性。我认为只指定httpsTransport就足够了。你这样做的方法是通过security tag。从它的声音,你需要设置authenticationMode="SspiNegotiated"

根据the custom binding docs

  

元素出现的顺序   堆栈很重要,因为它是   应用哪些操作的顺序   消息。推荐的订单   堆栈元素如下:

     

交易(可选)

     

可靠消息(可选)

     

安全(可选)

     

运输

     

编码器(可选)

有关自定义绑定安全性herehere的详细信息 希望这会有所帮助。

答案 1 :(得分:0)

这可能看起来很明显,但您是否检查过您仍然在开发服务器中传递“回调”查询参数?

查看JSONPEncoder源,它似乎仍然会向响应写入JSON消息,即使尚未收到“callback”参数。它不会格式化JavaScript方法包装器。