WCF服务和AspNetCompatibilityEnabled =“true”导致请求错误

时间:2012-09-19 20:46:27

标签: asp.net json wcf jsonp

我将WCF服务定义为:

[ServiceContract]
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Required)]
public class Service
{
    [OperationContract]
    [WebGet(ResponseFormat = WebMessageFormat.Json)]
    public string HelloWorld()
    {
        return "Hello World";
    }
}

我的Web.Config文件:

<configuration>
  <system.web>
    <compilation debug="true" targetFramework="4.0"/>
  </system.web>
  <system.serviceModel>
    <behaviors>
      <serviceBehaviors>
        <behavior name="">
          <serviceMetadata httpGetEnabled="true"/>
          <serviceDebug includeExceptionDetailInFaults="false"/>
        </behavior>
      </serviceBehaviors>
        <endpointBehaviors>
            <behavior name="webHttpBehavior">
                <webHttp />
            </behavior>
        </endpointBehaviors>
    </behaviors>
    <bindings>
      <webHttpBinding>
        <binding name="webHttpBindingWithJsonP" crossDomainScriptAccessEnabled="true"/>
      </webHttpBinding>
    </bindings>
    <services>
      <service name="Service">
        <endpoint address="" binding="webHttpBinding" bindingConfiguration="webHttpBindingWithJsonP" contract="Service" behaviorConfiguration="webHttpBehavior"/>
      </service>
    </services>
    <serviceHostingEnvironment multipleSiteBindingsEnabled="true" aspNetCompatibilityEnabled="true"/>
  </system.serviceModel>
</configuration>

我希望能够在我的WCF服务中访问ASP .Net会话变量,我希望WCF服务返回JSONP数据,但即使使用这个简单的服务,也可以浏览到../Service.svc/HelloWorld I我收到了400 Bad Request错误。

有人能指出我正确的方向吗?

2 个答案:

答案 0 :(得分:5)

看起来每个this Microsoft论坛都不支持JSONP,ASP.NET兼容性和经过身份验证的用户的组合。

根据论坛主持人的说法,您需要禁用其中一个。

可能不是您希望的答案,但主持人的解释非常好并提供了一些建议。

希望这会有所帮助。祝你好运!

答案 1 :(得分:0)

我意识到这已经得到了回答,但是有可能(尽管我不确定是否从安全角度推荐)要及早“解除验证”请求以通过webHttpBinding进行检查。

要点是将HttpContext.Current.User设置为基于GenericPrincipal构建的新GenericIdentity,没有名称或类型,如果未经身份验证的用户刚刚点击您的服务,则会模仿您所看到的内容 - 当webHttpBinding执行其“未经过身份验证的JSONP调用”时,检查请求是否在未经身份验证的用户的上下文中进行。

注意:我不确定这是否存在安全隐患 - 最重要的一点是,如果您有经过身份验证的用户,他们的会话状态仍可供您的服务使用可能是坏事,取决于你正在做什么。

你可以在几个地方做到这一点

  • 通过挂钩Application.AuthenticateRequest事件,按请求URL过滤
  • 使用自定义WCF邮件检查程序

示例消息检查器和行为元素(同一个类,非常多地使用,风险自负):

using System;
using System.Security.Principal;
using System.ServiceModel;
using System.ServiceModel.Channels;
using System.ServiceModel.Configuration;
using System.ServiceModel.Description;
using System.ServiceModel.Dispatcher;
using System.Threading;
using System.Web;

namespace MyNamespace
{
    public class ForceAnonymousEndpointBehavior : BehaviorExtensionElement, IDispatchMessageInspector, IEndpointBehavior
    {
        public override Type BehaviorType
        {
            get { return typeof(ForceAnonymousEndpointBehavior); }
        }

        protected override object CreateBehavior()
        {
            return new ForceAnonymousEndpointBehavior();
        }

        object IDispatchMessageInspector.AfterReceiveRequest(ref Message request, IClientChannel channel, InstanceContext instanceContext)
        {
            HttpContext.Current.User = Thread.CurrentPrincipal = new GenericPrincipal(new GenericIdentity("", ""), null);
            return null;
        }

        void IDispatchMessageInspector.BeforeSendReply(ref Message reply, object correlationState)
        {

        }

        void IEndpointBehavior.ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher)
        {
            endpointDispatcher.DispatchRuntime.MessageInspectors.Add(new ForceAnonymousEndpointBehavior());
        }

        void IEndpointBehavior.AddBindingParameters(ServiceEndpoint endpoint, BindingParameterCollection bindingParameters)
        {

        }

        void IEndpointBehavior.ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime)
        {

        }

        void IEndpointBehavior.Validate(ServiceEndpoint endpoint)
        {

        }
    }
}

然后在web.config中注册行为扩展(在system.serviceModel元素中):

<extensions>
  <behaviorExtensions>
    <add name="ForceAnonymous" type="MyNamespace.ForceAnonymousEndpointBehavior, MyAssembly" />
  </behaviorExtensions>
</extensions>

将行为添加到有问题的endpointBehavior(再次在system.serviceModel下):

<behaviors>
  <endpointBehaviors>
    <behavior name="jsonpBehavior">
      <ForceAnonymous />
    </behavior>
  </endpointBehaviors>
</behaviors>

...并确保通过设置behaviorConfiguration属性以匹配上面使用的行为名称,在服务的端点声明中调出端点行为。