具有自定义授权的负载均衡器背后的WCF服务

时间:2019-07-03 13:56:14

标签: wcf authorization load-balancing wshttpbinding f5

我们的环境基于服务器应用程序,该应用程序通过WCF公开服务。外出客户使用负载平衡器-F5。客户端应用程序通过安全通道访问它,后来它使用非安全HTTP通道。客户端和服务器都使用WsHttpBinding

客户端<> HTTPS <> F5 <> HTTP <>服务器

我设法使用了这种配置,但是我们的服务使用了基于JWT令牌的自定义授权,因此出现了问题。

我已经测试了许多配置,但是有很多错误。

当前客户端配置:

var binding = new WSHttpBinding();
binding.HostNameComparisonMode = HostNameComparisonMode.StrongWildcard;

binding.Security.Mode = SecurityMode.TransportWithMessageCredential;

binding.Security.Message.ClientCredentialType = MessageCredentialType.UserName;
binding.Security.Message.EstablishSecurityContext = false;
binding.Security.Message.NegotiateServiceCredential = true;

binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.None;
binding.Security.Transport.ProxyCredentialType = HttpProxyCredentialType.None;

服务器配置如下:

var binding = new WSHttpBinding();
binding.HostNameComparisonMode = HostNameComparisonMode.StrongWildcard;

host.Description.Behaviors.Find<ServiceBehaviorAttribute>().AddressFilterMode = AddressFilterMode.Any;

binding.Security.Mode = SecurityMode.None;

binding.Security.Message.ClientCredentialType = MessageCredentialType.UserName;
binding.Security.Message.EstablishSecurityContext = false;
binding.Security.Message.NegotiateServiceCredential = true;

binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.None;
binding.Security.Transport.ProxyCredentialType = HttpProxyCredentialType.None;

host.Description.Behaviors.Find<ServiceAuthorizationBehavior>().ServiceAuthorizationManager = new JWTAuthorizationManager();

客户端应用程序通过以下方式设置授权标头:

channelFactory.Credentials.UserName.UserName = userId;
credentialBehaviour.UserName.Password = token;

当前状态是请求转到服务,但是在JWTAuthorizationManager的CheckAccess()方法中,HttpRequestHeader.Authorization为空。此外,还会引发System.ServiceModel.MustUnderstandSoapException。当我将Security.Client的模式切换为Transport时,发生了同样的事情,但是没有引发异常。

我不熟悉这项技术的细节,也不确定会发生什么。

更新: 我检查了服务收到了什么。我看到消息中存在Security标头,但是由于Security Mode设置为None,服务无法解释这一点。我无法将其设置为Message,因为它需要服务器计算机上的证书,我们不希望这样做。

wireshark'ed message

1 个答案:

答案 0 :(得分:0)

我在服务器端使用CustomBinding解决了这个问题:

var binding = new CustomBinding();
var securityHeader = SecurityBindingElement.CreateUserNameOverTransportBindingElement();
securityHeader.AllowInsecureTransport = true;
securityHeader.MessageSecurityVersion = MessageSecurityVersion.WSSecurity10WSTrust13WSSecureConversation13WSSecurityPolicy12BasicSecurityProfile10;
securityHeader.SecurityHeaderLayout = SecurityHeaderLayout.Strict;
securityHeader.IncludeTimestamp = true;

var textEncoding = new TextMessageEncodingBindingElement();
textEncoding.MessageVersion = MessageVersion.Soap12WSAddressing10;
binding.Elements.Add(textEncoding);

var httpTransport = new HttpTransportBindingElement();
httpTransport.HostNameComparisonMode = HostNameComparisonMode.StrongWildcard;
httpTransport.MaxReceivedMessageSize = int.MaxValue;
httpTransport.MaxBufferPoolSize = int.MaxValue;
binding.Elements.Add(httpTransport);