WCF в IIS, используя MSMQ в режиме рабочей группы



Я пробовал MSMQ с WCF, но, кажется, не могу заставить его работать должным образом. У меня работает клиент (который отправляет сообщения в очередь), используя WCF и ссылку на службу. Код, который делает это, более или менее таков:



static void Main(string[] args)
{
var client = new MsmqServiceReference.MsmqContractClient();
client.SendMessage("TEST");
client.Close();
Console.ReadKey();
}


Где MsmqContractClient-это прокси, создаваемый visual studio при добавлении ссылки на службу. Конечная точка в приложении.config указывает на msmqueue:



<client>
<endpoint
address="net.msmq://localhost/private/MsmqService/MsmqService.svc"
binding="netMsmqBinding"
bindingConfiguration="MsmqBindingNonTransactionalNoSecurity"
contract="MsmqServiceReference.IMsmqContract" name="MsmqService" />
</client>


Это работает, сообщения отправляются в очередь.



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




Проверка привязки не удалась, поскольку
msmqauthenticationmode привязки
свойство имеет значение WindowsDomain но
MSMQ устанавливается с активным
Интеграция каталога с ограниченными физическими возможностями. То
фабрика каналов или узел обслуживания не могут
будьте открыты.




Вещи, которые я пробовал:





  • Предоставить всем полный доступ (включая анонимный вход в систему) к очередь



  • Настройка приложения для использования конкретной привязки из файла конфигурации с помощью:



    <bindings>
    <netMsmqBinding>
    <binding name="MsmqBindingNonTransactionalNoSecurity"
    deadLetterQueue="Custom"
    exactlyOnce="false">
    <security mode="None" />
    </binding>
    </netMsmqBinding>
    </bindings>



  • Я попытался запустить пул приложений в IIS (7) под своей учетной записью и учетной записью администратора



Что меня озадачивает, так это то, что он продолжает пытаться убедить меня, что я пытаюсь запустить его с помощью аутентификации WindowsDomain. Я заявил, что не хочу этого делать, когда режим безопасности установлен на нет, верно?



Мое приложение на данный момент-это просто webforms asp.net сайт с добавленной к нему службой WCF.



Если бы кто-нибудь мог хотя бы указать мне правильное направление, я был бы очень благодарен, так как уже потратил на это слишком много времени.



Создается впечатление, что конфигурация игнорируется или переопределяется. Полное сообщение об ошибке:



WebHost failed to process a request.
Sender Information: System.ServiceModel.Activation.HostedHttpRequestAsyncResult/63721755
Exception: System.ServiceModel.ServiceActivationException: The service '/MsmqService/MsmqService.svc' cannot be activated due to an exception during compilation. The exception message is: Binding validation failed because the binding's MsmqAuthenticationMode property is set to WindowsDomain but MSMQ is installed with Active Directory integration disabled. The channel factory or service host cannot be opened.. ---> System.InvalidOperationException: Binding validation failed because the binding's MsmqAuthenticationMode property is set to WindowsDomain but MSMQ is installed with Active Directory integration disabled. The channel factory or service host cannot be opened.
at System.ServiceModel.Channels.MsmqVerifier.VerifySecurity(MsmqTransportSecurity security, Nullable`1 useActiveDirectory)
at System.ServiceModel.Channels.MsmqVerifier.VerifyReceiver(MsmqReceiveParameters receiveParameters, Uri listenUri)
at System.ServiceModel.Channels.MsmqTransportBindingElement.BuildChannelListener[TChannel](BindingContext context)
at System.ServiceModel.Channels.BindingContext.BuildInnerChannelListener[TChannel]()
at System.ServiceModel.Channels.MessageEncodingBindingElement.InternalBuildChannelListener[TChannel](BindingContext context)
at System.ServiceModel.Channels.BinaryMessageEncodingBindingElement.BuildChannelListener[TChannel](BindingContext context)
at System.ServiceModel.Channels.BindingContext.BuildInnerChannelListener[TChannel]()
at System.ServiceModel.Channels.Binding.BuildChannelListener[TChannel](Uri listenUriBaseAddress, String listenUriRelativeAddress, ListenUriMode listenUriMode, BindingParameterCollection parameters)
at System.ServiceModel.Description.DispatcherBuilder.MaybeCreateListener(Boolean actuallyCreate, Type[] supportedChannels, Binding binding, BindingParameterCollection parameters, Uri listenUriBaseAddress, String listenUriRelativeAddress, ListenUriMode listenUriMode, ServiceThrottle throttle, IChannelListener& result, Boolean supportContextSession)
at System.ServiceModel.Description.DispatcherBuilder.BuildChannelListener(StuffPerListenUriInfo stuff, ServiceHostBase serviceHost, Uri listenUri, ListenUriMode listenUriMode, Boolean supportContextSession, IChannelListener& result)
at System.ServiceModel.Description.DispatcherBuilder.InitializeServiceHost(ServiceDescription description, ServiceHostBase serviceHost)
at System.ServiceModel.ServiceHostBase.InitializeRuntime()
at System.ServiceModel.ServiceHostBase.OnBeginOpen()
at System.ServiceModel.ServiceHostBase.OnOpen(TimeSpan timeout)
at System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout)
at System.ServiceModel.Channels.CommunicationObject.Open()
at System.ServiceModel.ServiceHostingEnvironment.HostingManager.ActivateService(String normalizedVirtualPath)
at System.ServiceModel.ServiceHostingEnvironment.HostingManager.EnsureServiceAvailable(String normalizedVirtualPath)
--- End of inner exception stack trace ---
at System.Runtime.AsyncResult.End[TAsyncResult](IAsyncResult result)
at System.ServiceModel.Activation.HostedHttpRequestAsyncResult.End(IAsyncResult result)
Process Name: w3wp
Process ID: 5660


Я попытался выяснить, что происходит с помощью Reflector, но просто кажется, что каким-то образом MsmqTransportBindingElement передается в процесс построения канала, который убежден, что он должен используйте WindowsDomain в качестве меры безопасности. Однако в моем конфигурационном файле для безопасности установлено значение none. Есть идеи о том, откуда берется это переопределяющее поведение?





Разрешение:



С одной стороны, я чувствую себя очень глупо, но с другой стороны, я чувствую, что есть место для улучшения.
Короткая версия заключается в том, что я перепутал значение атрибута 'name' в элементе service:

<services>
<service name="WcfService.MsmqService">
<!-- <endpoint binding="mexHttpBinding" contract="IMetadataExchange" />-->
<endpoint name="msmq"
address="net.msmq://localhost/private/MsmqService/MsmqService.svc"
binding="netMsmqBinding"
bindingConfiguration="NoSecurity"
contract="WcfService.IMsmqContract" />
</service>
</services>


Имя было таким же, как и у моего клиента, однако у клиента были привязки, созданные visual studio. Я дал ему другое имя (MsmqService), поэтому значение name было 'MsmqService.MsmqService'.



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

И да, теперь вы можете показывать пальцем и смеяться ; -)

663   4  

4 ответов:

Попробуйте эти настройки... useActiveDirectory по умолчанию должно быть false,но попробуйте. Режим аутентификации устанавливается на самом транспорте, поэтому msmqAuthenticationMode должно быть установлено значение "нет". msmqProtectionLevel и clientCredentialType звучат уместно, поэтому я бросил их туда же
:)


<bindings>
  <netMsmqBinding>
     <binding name="MsmqBindingNonTransactionalNoSecurity" 
          deadLetterQueue="Custom"
          useActiveDirectory="false" 
          exactlyOnce="false">
       <security mode="None">
         <transport 
            msmqAuthenticationMode="None"
            msmqProtectionLevel="None"
            clientCredentialType="None"/>
       </security>
     </binding>
  </netMsmqBinding>
</bindings>

Однако я был бы обеспокоен удалением всей системы безопасности... если вы находитесь в домене, вам следует установить MSMQ с интеграцией Active Directory или использовать методы рабочей группы для защиты сообщений.

Кроме того, не забывайте, параметры сервера и клиента должны совпадать.

HTH,
Джеймс

Извините за постоянные обновления, мое внимание к деталям сегодня кажется немного низким
: P

Не уверен, что это решит вашу конкретную проблему здесь, но есть действительно хорошая серия из трех частей блога Тома Холландера:

Кроме того, поскольку проблема, по-видимому, связана с Active Directory, вы пытались сказать своему Привязка MSMQ к тому, чтобы не использовать AD ??

<bindings>
  <netMsmqBinding>
     <binding name="MsmqBindingNonTransactionalNoSecurity" 
              deadLetterQueue="Custom" exactlyOnce="false"
              useActiveDirectory="false">   <== try this setting here!
        <security mode="None" />
     </binding>
  </netMsmqBinding>
</bindings>

Когда мы столкнулись с проблемой <security mode="None"> работал в тестовой среде.

Во время финальной доставки даже это не сработало.. Наконец, это сработало

<security>
<transport
msmqAuthenticationMode="None"
msmqProtectionLevel="None"/>
</security>

Деннис ван дер Стелт предоставляет хороший образец на WCF + MSMQ.

Вы также можете быть заинтересованы в этом Q/A на MSDN :

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

A: по умолчанию сообщения подписываются с помощью внутреннего сертификата MSMQ, для которого требуется служба каталогов Active Directory. В режиме рабочей группы, поскольку Active Directory не является доступно, подписать сообщение не удается. Таким образом, сообщение попадает в очередь мертвых писем, и причина сбоя, такая как "плохая подпись", указывается.

Обходной путь состоит в том, чтобы отключить безопасность. Это делается путем установки Mode = None, чтобы заставить его работать в режиме рабочей группы.

Другой обходной путь состоит в том, чтобы получить MsmqTransportSecurity из свойства Transport и установить его в Certificate, а затем установить сертификат клиента.

Еще одним обходным путем является установка MSMQ с активным Интеграция каталогов.

Comments

    Ничего не найдено.