我正在尝试在ASP.Net兼容模式下设置在IIS中托管的WCF服务,该模式通过表单身份验证进行保护,并通过IE中的.Net用户控件进行访问。 (见Secure IIS hosted WCF service for access via IE hosted user control)。
IE中的用户控件是必需的,因为它使用特定的第三方控件,在Silverlight或AJAX中不存在任何类似的控件。
因此,我需要UserControl在访问WCF服务之前在http请求标头中设置身份验证和会话ID。我的方法是设置一个消息检查器来执行此操作。
所以我定义了Message Inspector:
public class CookieInspector : IClientMessageInspector {
public void AfterReceiveReply(ref Message reply, object correlationState) {
}
public object BeforeSendRequest(
ref Message request,
IClientChannel channel) {
HttpRequestMessageProperty messageProperty;
if (request.Properties.ContainsKey(HttpRequestMessageProperty.Name)) {
messageProperty = (HttpRequestMessageProperty) request.Properties[
HttpRequestMessageProperty.Name
];
}
else {
messageProperty = new HttpRequestMessageProperty();
request.Properties.Add(
HttpRequestMessageProperty.Name,
messageProperty
);
}
// Set test headers for now...
messageProperty.Headers.Add(HttpRequestHeader.Cookie, "Bob=Great");
messageProperty.Headers.Add("x-chris", "Beard");
return null;
}
}
和端点行为:
public class CookieBehavior : IEndpointBehavior {
public void AddBindingParameters(
ServiceEndpoint endpoint,
BindingParameterCollection bindingParameters) {
}
public void ApplyClientBehavior(
ServiceEndpoint endpoint,
ClientRuntime clientRuntime) {
clientRuntime.MessageInspectors.Add(new CookieInspector());
}
public void ApplyDispatchBehavior(
ServiceEndpoint endpoint,
EndpointDispatcher endpointDispatcher) {
}
public void Validate(ServiceEndpoint endpoint) {
}
}
我在代码中配置和创建了我的频道和WCF客户端:
var ea = new EndpointAddress("http://.../MyService.svc");
// EDIT: Http cookies can't be set with WSHttpBinding :-(
// var binding = WSHttpBinding();
var binding = new BasicHttpBinding();
// Disable automatically managed cookies (which enables user cookies)
binding.AllowCookies = false;
binding.MaxReceivedMessageSize = 5000000;
binding.ReaderQuotas.MaxStringContentLength = 5000000;
var cf = new ChannelFactory<ITranslationServices>(binding, ea);
cf.Endpoint.Behaviors.Add(new CookieBehavior());
ITranslationServices service = cf.CreateChannel();
然而,当我用Fiddler查看我的请求时,http头和cookie没有设置,我不知道为什么。我已经阅读过关于网络,Stackoverflow等的各种文章,基本上说它应该可以工作,但事实并非如此。我错过了一些明显的东西,或者WCF中还有其他错误?
答案 0 :(得分:3)
好吧,我想通了,如果我使用basicHttpBinding而不是WSHttpBinding它可以工作。不知道为什么......
答案 1 :(得分:0)
WSHttpBinding
可以由一个以上的物理消息组成一个逻辑消息。因此,当进行连续的物理呼叫时,他们可能没有适当地携带cookie