C# Catch-22防止WIF保护的流式TCP WCF服务;毁了我的圣诞节精神健康
我需要使用WIF保护流式WCF net.tcp服务端点。它应该根据令牌服务器对传入呼叫进行身份验证。该服务是流式的,因为它被设计用于传输大量数据 这似乎是不可能的。如果我不能避开捕获物,我的圣诞节就会毁了,我会在阴沟里喝得烂醉如泥,而快乐的购物者会踩在我慢慢冷却的身体上。伙计们,说真的 为什么这是不可能的?这是第二十二条军规 在客户机上,我需要使用从令牌服务器获取的信息创建一个通道。没问题C# Catch-22防止WIF保护的流式TCP WCF服务;毁了我的圣诞节精神健康,c#,wcf,.net-4.5,wif,nettcpbinding,C#,Wcf,.net 4.5,Wif,Nettcpbinding,我需要使用WIF保护流式WCF net.tcp服务端点。它应该根据令牌服务器对传入呼叫进行身份验证。该服务是流式的,因为它被设计用于传输大量数据 这似乎是不可能的。如果我不能避开捕获物,我的圣诞节就会毁了,我会在阴沟里喝得烂醉如泥,而快乐的购物者会踩在我慢慢冷却的身体上。伙计们,说真的 为什么这是不可能的?这是第二十二条军规 在客户机上,我需要使用从令牌服务器获取的信息创建一个通道。没问题 // people around here hate the Framework Design Guide
// people around here hate the Framework Design Guidelines.
var token = Authentication.Current._Token;
var service = base.ChannelFactory.CreateChannelWithIssuedToken(token);
return service.Derp();
我说“没问题”了吗?问题。事实上,NullReferenceException
风格问题
“兄弟,”我问框架,“你有空检查吗?”框架没有声音,所以我拆开后发现
((IChannel)(object)tChannel).
GetProperty<ChannelParameterCollection>().
Add(federatedClientCredentialsParameter);
好极了。再也没有了。然而,现在我的客户在出生时就犯了错误(tho,我仍然爱他)。通过挖掘WCF诊断(protip:让你最坏的敌人在击溃他们并将他们赶在你前面,但在享受他们的妇女和孩子的哀叹之前这样做),我发现这是因为服务器和客户端之间的安全不匹配
“net”不支持请求的升级。tcp://localhost:49627/MyService'. 这可能是由于绑定不匹配(例如,在客户端而不是服务器上启用了安全性)
检查主持人的诊断(再次:粉碎、驾驶、阅读日志、享受哀悼),我发现这是真的
协议类型application/ssl tls已发送到不支持该类型升级的服务
“好吧,赛尔夫,”我说,“我会在主机上打开消息安全!”我做到了。如果您想知道它是什么样子,它是客户机配置的精确副本。抬头看
结果:Kaboom.
绑定('NetTcpBinding','')支持流式传输,而流式传输不能与消息级安全一起配置。考虑选择不同的传输模式或选择传输级安全性。
因此,我的主机不能通过令牌进行流式传输和安全保护。第二十二条军规
tl;dr:如何使用WIF保护流式net.tcp WCF端点?WCF在流式传输的一些领域(我在看你,MTOM1)遇到了一个基本问题,即它如何无法按照大多数人认为的方式执行预验证(它只影响该频道的后续请求,而不是第一个请求)好的,所以这不完全是您的问题,但请继续,因为我将在最后讨论您的问题。通常HTTP质询的工作方式如下:
internal class BasicAuthenticationBehavior : IEndpointBehavior
{
private readonly string _username;
private readonly string _password;
public BasicAuthenticationBehavior(string username, string password)
{
this._username = username;
this._password = password;
}
public void AddBindingParameters(ServiceEndpoint endpoint,
BindingParameterCollection bindingParameters) { }
public void ApplyClientBehavior(ServiceEndpoint endpoint,
ClientRuntime clientRuntime)
{
var inspector = new BasicAuthenticationInspector(
this._username, this._password);
clientRuntime.MessageInspectors.Add(inspector);
}
public void ApplyDispatchBehavior(ServiceEndpoint endpoint,
EndpointDispatcher endpointDispatcher) { }
public void Validate(ServiceEndpoint endpoint) { }
}
internal class BasicAuthenticationInspector : IClientMessageInspector
{
private readonly string _username;
private readonly string _password;
public BasicAuthenticationInspector(string username, string password)
{
this._username = username;
this._password = password;
}
public void AfterReceiveReply(ref Message reply,
object correlationState) { }
public object BeforeSendRequest(ref Message request,
IClientChannel channel)
{
// we add the headers manually rather than using credentials
// due to proxying issues, and with the 101-continue http verb
var authInfo = Convert.ToBase64String(
Encoding.Default.GetBytes(this._username + ":" + this._password));
var messageProperty = new HttpRequestMessageProperty();
messageProperty.Headers.Add("Authorization", "Basic " + authInfo);
request.Properties[HttpRequestMessageProperty.Name] = messageProperty;
return null;
}
}
因此,本示例适用于任何遭受MTOM问题困扰的人,但也可以作为实现类似于验证主要WIF安全令牌服务生成的令牌的框架
希望这有帮助
(一)
(2) (请参阅“缺点”)好的,这里可能有一个无知的问题,但WIF真的需要消息模式吗?传输模式听起来像是w
internal class BasicAuthenticationBehavior : IEndpointBehavior
{
private readonly string _username;
private readonly string _password;
public BasicAuthenticationBehavior(string username, string password)
{
this._username = username;
this._password = password;
}
public void AddBindingParameters(ServiceEndpoint endpoint,
BindingParameterCollection bindingParameters) { }
public void ApplyClientBehavior(ServiceEndpoint endpoint,
ClientRuntime clientRuntime)
{
var inspector = new BasicAuthenticationInspector(
this._username, this._password);
clientRuntime.MessageInspectors.Add(inspector);
}
public void ApplyDispatchBehavior(ServiceEndpoint endpoint,
EndpointDispatcher endpointDispatcher) { }
public void Validate(ServiceEndpoint endpoint) { }
}
internal class BasicAuthenticationInspector : IClientMessageInspector
{
private readonly string _username;
private readonly string _password;
public BasicAuthenticationInspector(string username, string password)
{
this._username = username;
this._password = password;
}
public void AfterReceiveReply(ref Message reply,
object correlationState) { }
public object BeforeSendRequest(ref Message request,
IClientChannel channel)
{
// we add the headers manually rather than using credentials
// due to proxying issues, and with the 101-continue http verb
var authInfo = Convert.ToBase64String(
Encoding.Default.GetBytes(this._username + ":" + this._password));
var messageProperty = new HttpRequestMessageProperty();
messageProperty.Headers.Add("Authorization", "Basic " + authInfo);
request.Properties[HttpRequestMessageProperty.Name] = messageProperty;
return null;
}
}