2

我有一个 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 我也会得到一个400 错误请求错误。

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

4

2 回答 2

5

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

根据论坛版主的说法,您需要禁用这三个中的一个。

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

希望这可以帮助。祝你好运!

于 2012-09-19T21:22:38.970 回答
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>

将行为添加到有问题的端点行为(同样在 system.serviceModel 下):

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

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

于 2013-10-01T11:07:17.273 回答