Аутентификация WCF NT Challenge ответ - PullRequest
0 голосов
/ 29 марта 2011

Как я могу заставить мое консольное приложение подключаться к службе WCF, размещенной на IIS, когда включена обычная проверка подлинности и / или проверка подлинности Windows и анонимная проверка подлинности отключена?

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

Я искал несколько дней и перепробовал много способов, включая использование собственного сертификата и переопределение проверки сертификации, переопределение UserNameValidator и использование client.ClientCredentials.Windows.ClientCredentials.UserName или client.ClientCredentials.UserName.UserName.Ничто из этого не сработало.

Я нахожусь в такой ситуации, когда было бы неплохо, если бы кто-то был так любезен, посмотрел и выполнил код и помог мне запустить пример с аутентификацией.

Я позволил себе загрузить решение для песочницы, содержащее проекты HostWebSite, ClientConsole и API.

Я разместил zip-файл на моем Windows Live SkyDrive: WCF_Authentication.zip

Некоторые небольшие шаги установки.

  1. Я добавил в файл hosts 127.0.0.1 hostwebsite.local

  2. Я добавил сайт в IIS
    - местоположение: HostWebSite project root,
    - привязка: hostwebsite.local
    - пул приложений: Classic 4.0 app pool.

  3. Прикладная защита Everyone доступ на чтение к каталогу проекта HostWebSite.

  4. Убедитесь, что можете видеть сервис http://hostwebsite.local/services/EchoService.svc

  5. Убедитесь, что консоль эхом возвращается в мир приветствия.

  6. Затем отключите анонимный доступ через IIS / Аутентификацию и включите базовую аутентификацию и / или проверку подлинности Windows.

спасибо

ЗаДля удобства читателей я включил здесь фрагменты кода
Проект: API

namespace API.Contract
{
    [ServiceContract]
    public interface IEcho
    {
        [OperationContract]
        string SendEcho(string message);
    }
}
namespace API.Proxy
{
    public class EchoProxy : IEcho
    {
        public string SendEcho(string message)
        {
            return string.Concat("You said: ", message);
        }
    }
}
namespace API.Service
{
    [System.Diagnostics.DebuggerStepThroughAttribute()]
    [System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")]
    public class EchoService : System.ServiceModel.ClientBase<IEcho>, IEcho
    {

        public EchoService()
        {
        }

        public EchoService(string endpointConfigurationName) :
            base(endpointConfigurationName)
        {
        }

        public EchoService(string endpointConfigurationName, string remoteAddress) :
            base(endpointConfigurationName, remoteAddress)
        {
        }

        public EchoService(string endpointConfigurationName, System.ServiceModel.EndpointAddress remoteAddress) :
            base(endpointConfigurationName, remoteAddress)
        {
        }

        public EchoService(System.ServiceModel.Channels.Binding binding, System.ServiceModel.EndpointAddress remoteAddress) :
            base(binding, remoteAddress)
        {
        }

        public string SendEcho(string message)
        {
            return base.Channel.SendEcho(message);
        }
    }
}

Проект: ClientConsole

static void Main(string[] args)
{
    EchoService client = new EchoService("WSHttpBinding_IEcho");

    try
    {
        Console.WriteLine(client.SendEcho("Hello World"));
        client.Close(); // i tried putting this in the finally block but the client would close in an errored state it said.
    }
    catch (Exception ex)
    {
        Console.WriteLine(ex.Message);
    }
    finally
    {

    }


    Console.WriteLine("Press any key to exit.");
    Console.ReadKey();
}

Конфиг клиента

<system.serviceModel>
    <bindings>
        <wsHttpBinding>
            <binding name="WSHttpBinding_IEcho" closeTimeout="00:01:00" openTimeout="00:01:00"
                receiveTimeout="00:10:00" sendTimeout="00:01:00" bypassProxyOnLocal="false"
                transactionFlow="false" hostNameComparisonMode="StrongWildcard"
                maxBufferPoolSize="524288" maxReceivedMessageSize="65536"
                messageEncoding="Text" textEncoding="utf-8" useDefaultWebProxy="true"
                allowCookies="false">
                <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
                    maxBytesPerRead="4096" maxNameTableCharCount="16384" />
                <reliableSession ordered="true" inactivityTimeout="00:10:00"
                    enabled="false" />
                <security mode="Message">
                    <transport clientCredentialType="Windows" proxyCredentialType="None"
                        realm="" />
                    <message clientCredentialType="Windows" negotiateServiceCredential="true"
                        algorithmSuite="Default" />
                </security>
            </binding>
        </wsHttpBinding>
    </bindings>
    <client>
        <endpoint address="http://hostwebsite.local/Services/EchoService.svc/services/EchoService.svc"
            binding="wsHttpBinding" bindingConfiguration="WSHttpBinding_IEcho"
            contract="API.Contract.IEcho" name="WSHttpBinding_IEcho">
            <identity>
                <servicePrincipalName value="host/mikev-ws" />
            </identity>
        </endpoint>
    </client>
</system.serviceModel>

Проект: HostWebSite

<system.serviceModel>
    <!-- SERVER -->
    <behaviors>
        <serviceBehaviors>
            <behavior name="MyServiceTypeBehaviors">
                <serviceMetadata httpGetEnabled="true" />
                <serviceDebug includeExceptionDetailInFaults="true" />
            </behavior>
        </serviceBehaviors>
    </behaviors>
    <services>
        <service name="API.Proxy.EchoProxy" behaviorConfiguration="MyServiceTypeBehaviors">
            <endpoint address="/services/EchoService.svc" binding="wsHttpBinding" contract="API.Contract.IEcho" />
            <endpoint contract="IMetadataExchange" binding="mexHttpBinding" address="mex"/>
        </service>
    </services>
    <serviceHostingEnvironment multipleSiteBindingsEnabled="true"/>

</system.serviceModel>

1 Ответ

1 голос
/ 29 марта 2011

Вы действительно смотрите на уровень безопасности сообщений?Из вашего описания видно, что вы хотите безопасность на транспортном уровне (из IIS).Для этого вы должны получить правильный файл конфигурации вашего клиента.Например,

<binding ...
   ...
   <security mode="TransportCredentialOnly">
       <transport clientCredentialType="windows" proxyCredentialType="None" realm="" />
...

Это обеспечит встроенную проверку подлинности Windows - будет использовать текущий пользователь Windows, выполняющий клиент для проверки подлинности.Для аутентификации NTLM / BASIC необходимо указать имя пользователя / пароль из кода - например,

<binding ...
       ...
       <security mode="TransportCredentialOnly">
           <transport clientCredentialType="Ntlm" proxyCredentialType="None" realm="" />

А в коде

EchoService client = new EchoService("WSHttpBinding_IEcho");
client.ClientCredentials.Windows.ClientCredential = new System.Net.NetworkCredential(userName, pwd);

РЕДАКТИРОВАТЬ :

Чтобы базовая аутентификация работала с протоколом http, вам необходимо выполнить настройку на стороне сервера, а также.Например,

<system.serviceModel>
    <!-- SERVER -->
    <bindings>
        <basicHttpBinding>
            <binding name="NewBinding">
                <security mode="TransportCredentialOnly">
                    <transport clientCredentialType="Basic" />
                </security>
            </binding>
        </basicHttpBinding>
    </bindings>
    ...
    <services>
        <service name="API.Proxy.EchoProxy" ...
           <endpoint binding="basicHttpBinding" bindingConfiguration="NewBinding" contract="API.Contract.IEcho" />
      ...

См. эту статью для получения дополнительной информации.Кстати, вы можете рассмотреть схему HTTPS, потому что базовая аутентификация передает пароль в виде простого текста.

...