Сеансы WCF с wsHttpBinding и без защиты Windows - PullRequest
11 голосов
/ 22 января 2011

Мне нужно создать службу WCF, которая размещается в IIS, использует http-транспорт и удерживает состояние в памяти сервера.Хотя я знаю, что службы с сохранением состояния не являются хорошей идеей, последнее ограничение необходимо для того, чтобы служба работала с устаревшим клиентом.

Сначала я подумал о сеансе asp.net для хранения значений.Я активировал режим совместимости asp.net в своем сервисе, который дал мне доступ к HttpContext, но значения, которые были помещены в объект сеанса, не сохранялись в памяти.Я предполагаю, что это произошло из-за того, что модуль http, который обрабатывает состояние сеанса, был настроен неправильно, но при поиске ответа я наткнулся на сеансы WCF и подумал, что было бы лучше использовать их.

Однако сеансы WCFкажется, что недостаточно документировано и помещает странный набор предварительных требований в службу, и я не смог найти конфигурацию, которая соответствует моим потребностям: должен быть размещен в IIS, должен использовать транспорт http или https и не может отвечать напроверка подлинности Windows, потому что клиент и сервер не будут частью одного домена.Я пытаюсь добиться этого, используя wsHttpBinding, я слышал, что сеансам WCF требовалось либо сообщение безопасности, либо надежное сообщение, но: - При использовании стандартной привязки, и когда серверы не являются частью одного домена, происходит сбой с «SecurityNegotiationExceptionне был аутентифицирован сервисом »исключение.Это довольно логично, так как в нем использовалась защита Windows.

  • Если отключить защиту завершена, произойдет сбой с «контрактом требуется сеанс, но привязка« WSHttpBinding »не поддерживает его или не является»не настроен должным образом для его поддержки ».

  • Если при сохранении безопасности отключено, я включаю надежное сообщение и получаю исключение« Проверка привязки завершилась неудачно, поскольку WSHttpBinding не поддерживает надежные сеансы по транспортной безопасности (HTTPS).).Не удалось открыть фабрику каналов или хост-службу.Используйте безопасность сообщений для безопасного и надежного обмена сообщениями по HTTP. ”

  • Я пытался включить защиту на транспортном уровне, но, похоже, это не имеет никакого значения для сгенерированной ошибки

Есть ли какая-нибудь конфигурация, которая может работать для меня?Или мне просто вернуться к плану использования сессий asp.net?

Ответы [ 2 ]

25 голосов
/ 22 января 2011

WCF может хранить информацию о сеансе в памяти довольно простым способом. Чтобы исключить любые возможные внешние воздействия в моих инструкциях, я предполагаю, что вы начинаете с совершенно нового проекта:

  1. Создайте новый проект библиотеки сервисов WCF. Этот проект уже будет содержать службу с предварительно настроенной привязкой WSHttpBiding.
  2. Перейдите к контракту на обслуживание (IService1.cs) и измените атрибут ServiceContract на следующий:

    [ServiceContract(SessionMode = SessionMode.Required)]
    
  3. Перейдите к реализации службы (Service1.cs) и добавьте следующий атрибут ServiceBehavior в класс службы (Service1):

    [ServiceBehavior(InstanceContextMode = InstanceContextMode.PerSession, ConcurrencyMode = ConcurrencyMode.Single)]
    
  4. Добавление данных сеанса в качестве членов класса обслуживания (Service1):

    public class Service1 : IService1
    {
        ...
    
        private string UserFullName { get; set; }
    
        ...
    }
    
  5. Используйте участников для представления специфичных для сеанса данных (не забудьте также добавить их в контракт на обслуживание, IService1):

    public class Service1 : IService1
    {
        ...
    
        public string Welcome(string fullName)
        {
            UserFullName = fullName ?? "Guest";
            return string.Format("Welcome back, {0}!", UserFullName);
        }
    
        public string Goodbye()
        {
            return string.Format("Come back soon, {0}!", UserFullName ?? "Guest");
        }
    
        ...
    }
    

SessionMode.Required обеспечивает отслеживание сеансов ваших клиентов.
InstanceContextMode.PerSession гарантирует, что экземпляр вашего класса обслуживания (Service1) будет создан для каждого сеанса, чтобы вы могли сохранять в нем данные сеанса, и они будут существовать в памяти при нескольких вызовах в одном сеансе.
ConcurrencyMode.Single гарантирует, что только один поток может войти в каждый экземпляр класса обслуживания (Service1), и предотвращает возможные проблемы параллелизма, если вы только получаете доступ к данным из класса обслуживания (и внешних безопасных для потоков расположений).

РЕДАКТИРОВАТЬ: По умолчанию WSHttpBinding разрешает только сеансы безопасности. Но он также поддерживает надежные сеансы, которые позволяют устанавливать сеансы без включенной защиты. Следующая конфигурация привязки отключает безопасность и включает надежные сеансы:

<wsHttpBinding>
    <binding name="wsHttpBindingConfiguration">
        <security mode="None" />
        <reliableSession enabled="true" />
    </binding>
</wsHttpBinding>
1 голос
/ 22 января 2011

IMO это то, что происходит, когда вы используете технологию с плохой абстракцией по HTTP, такую ​​как WCF.Тот факт, что веб-сервисы WCF теоретически могут быть размещены без HTTP (т. Е. Через NET TCP, MSMQ и т. Д.), Просто затрудняет использование встроенных функций HTTP без входа в ад настройки и запускает игру «угадайте правильную конфигурацию»методом проб и ошибок ", где вы пробуете все возможные конфигурации перестановки, пока не найдете правильную работающую!

В конечном итоге, если вы не можете использовать WCF и вам нужно было реализовать веб-сервис с нуля, вы просто установитеcookie, когда клиент успешно прошел аутентификацию.Затем с каждым клиентским запросом просто получайте информацию о сеансе, на которую ссылается этот файл cookie.

Одно из возможных решений, если вам пришлось использовать WCF, - это взять управление сеансом в свои руки (Это то, что я делаю, когда я 'я недоволен усилиями, необходимыми для того, чтобы заставить что-то работать) и имею явное свойство 'Session' для всех ваших веб-сервисов, которые требуют сеанса / аутентификации (обычно это guid, генерируемый при аутентификации).Таким образом, для каждого последующего запроса вы используете гид для повторной обработки информации о сеансе, связанной с этим клиентом.

Если вы заинтересованы в испытании различных структур веб-служб, я поддерживаю Open Source Web Services Framework это позволяет создавать неконфигурируемые, СУХИЕ, тестируемые веб-сервисы, где (без какой-либо конфигурации) каждый создаваемый веб-сервис автоматически доступен через конечные точки REST XML, JSON, JSV, SOAP 1.1, SOAP 1.2.По сути, он позволяет вам получить доступ к той же веб-службе через URL-адрес HTTP GET для клиентов REST-ful и простую отладку, а также конечные точки SOAP (популярный выбор, который по-прежнему требуется некоторыми предприятиями).Учебное пособие Hello World должно дать вам хорошее представление о некоторых его функциях и о том, как оно работает.

...