WCF: запрос маркера безопасности не может быть удовлетворен из-за сбоя проверки подлинности

У меня есть две службы WCF на одной машине. Один - издатель, а другой - слушатель.

Издатель динамически создает прокси на основе конечной точки. Я настраиваю прокси в таком коде:

            WSHttpBinding binding = new WSHttpBinding(SecurityMode.Message, true);
            binding.Security.Message.NegotiateServiceCredential = true;
            binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Windows;
            binding.Security.Transport.ProxyCredentialType = HttpProxyCredentialType.None;
            binding.Security.Message.ClientCredentialType = MessageCredentialType.Windows;
            binding.Security.Message.EstablishSecurityContext = true;
            binding.ReliableSession.Enabled = true;
            binding.TransactionFlow = true;
            return binding;

а потом...

            Binding binding = GetBindingFromAddress(address);

            ChannelFactory<T> factory = new ChannelFactory<T>(binding);
            factory.Credentials.UserName.UserName = "an account on the machine";
            factory.Credentials.UserName.Password = "a password for that account";

            T proxy = factory.CreateChannel(new EndpointAddress(address));

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

   <service behaviorConfiguration="MEX Enabled" name="InvoiceSubscriber">
<endpoint binding="wsHttpBinding"
          bindingConfiguration="ReliableTransactionalHTTP"
          contract="AtlanticBT.SubscriptionService.Contracts.v1.IAtlanticEvents">
 <identity>
  <dns value="localhost" />
 </identity>
</endpoint>

        <bindings>
        <wsHttpBinding>
            <binding name="ReliableTransactionalHTTP" transactionFlow="true">
                <reliableSession enabled="true"/>
      <security mode="Message">
        <transport clientCredentialType="Windows" proxyCredentialType="None" realm=""/>
        <message clientCredentialType="Windows" negotiateServiceCredential="true" 
                 algorithmSuite="Default" establishSecurityContext="true"/>
      </security>
            </binding>
  </wsHttpBinding>
    </bindings>

I have checked all my ACL on the directories that host the services and they appear to be correct. IIS security is set to Anonymous access and Windows Authentication.

Итак, если я явно устанавливаю учетные данные в коде, почему мой слушатель не может пройти аутентификацию?


person Daryl    schedule 28.10.2009    source источник
comment
Сам запрос может иметь неправильный формат. Используйте Fiddler, чтобы проверить необработанный запрос / ответ, чтобы убедиться, что вы передаете действительно правильный запрос. fiddler2.com/fiddler2   -  person Mike Atlas    schedule 29.10.2009
comment
Ах, скрипач ... Я забыл об этой маленькой уловке. Я постараюсь посмотреть. Мне также нужно разработать сценарии аутентификации. Спасибо!   -  person Daryl    schedule 29.10.2009


Ответы (1)


Во-первых, это сообщение обычно означает, что машины не находятся в одном домене и, следовательно, не могут обмениваться данными с использованием безопасности Windows. Два сервера находятся в одном домене?

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

В-третьих, все, что вы настроили, говорит: «Я хочу использовать проверку подлинности Windows», но затем вы устанавливаете свойства UsernameClientCredentials для ClientCredentials. Эти свойства используются только для защиты токена имени пользователя, а не для Windows. Безопасность Windows будет использовать идентификатор текущего потока и пересылать его.

Предполагая, что вы намеревались использовать систему безопасности Windows, вам необходимо:

  1. Запустите свой издательский процесс под одним идентификатором Windows, под которым вы хотите, чтобы он общался с подписчиками.
  2. Используйте олицетворение в процессе издателя, чтобы изменить контекст безопасности для каждого вызова (см. WindowsIdentity. Чтобы получить дополнительную информацию, выдавайте себя за другое лицо)

Прямо сейчас вы технически делаете №1, даже если думаете, что делаете №2, устанавливая свойства имени пользователя и пароля, поскольку они игнорируются.

Наконец, вот хорошая документация о том, как настроить привязки для различных сценариев проверки подлинности Windows:


Помимо этого, я не уверен, что еще я могу дать без дополнительной информации от вас. Если вы измените свой вопрос, чтобы предоставить дополнительную информацию / ответить на некоторые из моих вопросов, я с радостью пересмотрю свой ответ, чтобы, надеюсь, сделать его более полезным.

person Drew Marsh    schedule 29.10.2009
comment
Дрю - большое спасибо за ответ. Я собираюсь подготовить упомянутые вами статьи и ответить позже в тот же день. Я намерен использовать аутентификацию Windows. Службы находятся на одном компьютере и работают в одном домене. Спасибо! - person Daryl; 29.10.2009
comment
Мне нужно было учитывать два сценария. Является ли эта услуга обслуживанием, я определенно хотел Windows Security. Я настроил IIS только для проверки подлинности Windows (позволяя ThreadCurrentPrincipal быть вызывающим) и удалил ClientCredentials. Для клиентов, отличных от Windows, я собираюсь изучить использование безопасности токена имени пользователя или безопасности на основе сертификатов. Я уже в пути благодаря твоему сообщению ... спасибо за статьи, они были ОЧЕНЬ полезными. Дэрил - person Daryl; 02.11.2009