我将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错误。
有人能指出我正确的方向吗?
答案 0 :(得分:5)
看起来每个this Microsoft论坛都不支持JSONP,ASP.NET兼容性和经过身份验证的用户的组合。
根据论坛主持人的说法,您需要禁用其中一个。
可能不是您希望的答案,但主持人的解释非常好并提供了一些建议。
希望这会有所帮助。祝你好运!
答案 1 :(得分:0)
我意识到这已经得到了回答,但是有可能(尽管我不确定是否从安全角度推荐)要及早“解除验证”请求以通过webHttpBinding进行检查。
要点是将HttpContext.Current.User
设置为基于GenericPrincipal
构建的新GenericIdentity
,没有名称或类型,如果未经身份验证的用户刚刚点击您的服务,则会模仿您所看到的内容 - 当webHttpBinding执行其“未经过身份验证的JSONP调用”时,检查请求是否在未经身份验证的用户的上下文中进行。
注意:我不确定这是否存在安全隐患 - 最重要的一点是,如果您有经过身份验证的用户,他们的会话状态仍可供您的服务使用可能是坏事,取决于你正在做什么。
你可以在几个地方做到这一点
示例消息检查器和行为元素(同一个类,非常多地使用,风险自负):
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
属性以匹配上面使用的行为名称,在服务的端点声明中调出端点行为。