Наша среда основана на серверном приложении, которое предоставляет услуги через 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 пусто. Кроме того, создается исключение System.ServiceModel.MustUnderstandSoapException. Когда я переключил Security.Mode клиента на Transport, происходит то же самое, но исключение не выдается.
Я не знаком с деталями этой технологии и не уверен, что происходит на самом деле.
ОБНОВЛЕНИЕ: я проверил, что получает служба. Я вижу, что в сообщении есть заголовок безопасности, но служба не может его интерпретировать, поскольку для режима безопасности установлено значение «Нет». Я не могу установить для этого значение «Сообщение», потому что для этого требуется сертификат на сервере, а нам это не нужно.