Служба WCF за loadbalancer с пользовательской авторизацией - PullRequest
0 голосов
/ 03 июля 2019

Наша среда основана на серверном приложении, которое предоставляет сервис через 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;

Текущее состояние: запрос отправляется в службу, но в методе CheckAccess () из JWTAuthorizationManager HttpRequestHeader.Authorization isпустой.Кроме того, исключение System.ServiceModel.MustUnderstandSoapException.Когда я переключил Security.Mode клиента на Transport, происходит то же самое, но исключение не выдается.

Я не знаком с деталями этой технологии и не уверен, что на самом деле происходит.

ОБНОВЛЕНИЕ: Я проверил, что получает служба.Я вижу, что заголовок Security существует в сообщении, но служба не может интерпретировать это из-за того, что Security Mode имеет значение None.Я не могу установить для этого Сообщение, потому что это требует сертификата на сервере, мы не хотим этого.

wireshark'ed message

1 Ответ

0 голосов
/ 05 июля 2019

Я справился с этой проблемой, используя 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);
...