WCF自定义JSONP绑定和httpsTransport

13

我的问题围绕着一个响应JSONP的IIS WCF REST服务。我使用了这个解决方案中的类:http://msdn.microsoft.com/en-us/library/cc716898.aspx,并将它们添加到我的项目中。在我的开发工作站上,使用httpTransport进行模拟时一切都很顺利,但当我尝试转移到开发服务器时,遇到了一些安全问题。我使用以下配置和App Pool身份用户解决了这些问题,并且还为NTLM认证配置了IIS metabase文件(我们正在使用IIS 6但很快会是IIS 7,需要在两个版本上工作),因为我没有权限创建SPN。我相信当前的配置解决了我的安全问题,但在此过程中,我的JSONP响应被降级为普通的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个回答

1

我不确定答案是否正确,但以下是一些有助于缩小范围的东西:

首先,如果您将ProtectionLevel 明确设置为 Sign 或 EncryptAndSign,则必须使用启用了安全性的绑定,否则将引发异常。如果尝试通过 http 访问它,这将开始抛出异常,这可以帮助您找出您实际上是如何访问服务的。

其次,由于您正在使用 customBinding,因此您需要告诉它绑定中要使用的安全类型。仅指定 httpsTransport 是不够的。您可以通过 security tag 来完成。从听起来的方式来看,您需要设置 authenticationMode="SspiNegotiated"

根据 自定义绑定文档

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

事务(可选)

可靠消息传递(可选)

安全性(可选)

传输

编码器(可选)

更多关于自定义绑定安全性的信息在这里在这里 希望这有所帮助。

0
这可能看起来很明显,但你是否检查过在开发服务器中是否仍然传递了“callback”查询参数?
从JSONPEncoder源代码来看,即使没有收到“callback”参数,它似乎仍会向响应写入JSON消息。它只是不会格式化JavaScript方法包装器。

谢谢,在您的评论后我进行了双重检查,回调查询参数在两个环境中都存在。需要注意的一点是,当我将配置从httpTransport更改为HttpsTransport时,本地系统的输出变成了常规json格式。 - user175106
奇怪。你说你已经包含了示例中的类。如果你在JSONPEncoderFactory的两个WriteMessage方法中都设置断点,当你进行调用时它们中的任何一个被命中了吗? - Matthew Pelser

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接