2011-01-22 4 views
11

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

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

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

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

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

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

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

+0

Обнаружено, что сеанс asp.net не работает, поскольку файлы cookie отключены, имеют рабочую версию кода с использованием сеансов asp.net. – Robert

ответ

25

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

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

    [ServiceContract(SessionMode = SessionMode.Required)] 
    
  3. Перейти к implimentation службы (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) и предотвращает возможные проблемы параллелизма, если вы получаете доступ только к данным из класса обслуживания (а также к внешним потокобезопасным местоположениям).

EDIT: По умолчанию WSHttpBinding разрешает сеансы безопасности. Но он также поддерживает надежные сеансы, которые позволяют устанавливать сеансы без обеспечения безопасности. Следующая конфигурация привязки отключает безопасность и обеспечивает надежные сеансы:

<wsHttpBinding> 
    <binding name="wsHttpBindingConfiguration"> 
     <security mode="None" /> 
     <reliableSession enabled="true" /> 
    </binding> 
</wsHttpBinding> 
+0

Это более или менее то, что я сделал, кажется, что для проверки подлинности Windows уровня сообщений требуется. Это не вариант для меня, поскольку клиент и сервер не будут находиться в одном домене. – Robert

+0

@Robert: правильно, но есть решение. См. Изменение в моем ответе. Надеюсь, это решит вашу проблему. –

+0

Используя вашу предложенную конфигурацию на клиенте, я получаю следующую ошибку. ProtocolException: удаленная конечная точка отправила непризнанную ошибку с пространством имен, http://www.w3.org/2003/05/soap-envelope, отправитель имени и причину. Сообщение не может быть обработано. Это, скорее всего, потому, что действие «http://schemas.xmlsoap.org/ws/2005/02/rm/CreateSequence» неверно или потому, что сообщение содержит недействительный или истекший токен контекста безопасности или потому, что есть .. – Robert

1

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

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

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

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

+0

Спасибо за ответ! Хотя я согласен в основном с вашим ответом, это неудачное ограничение проекта, которое мы должны использовать WCF. Я обязательно взгляну на ServiceStack для проектов с менее строгими ограничениями на технологии, которые будут использоваться. – Robert