HTTP-запрос не авторизован с помощью схемы аутентификации клиента «Basic». Заголовок аутентификации, полученный от сервера, был 'Basic realm = "pc"' - PullRequest
16 голосов
/ 19 декабря 2009

Сервер:

<system.serviceModel>
    <services>
        <service name="Service" behaviorConfiguration="md">
            <!-- Service Endpoints -->
            <endpoint address="SslService" binding="basicHttpBinding" bindingConfiguration="security" contract="IService"/>
            <host>
                <baseAddresses>
                    <add baseAddress="https://pc:8080/Service.svc"/>
                </baseAddresses>
            </host>
        </service>
    </services>
    <bindings>
        <basicHttpBinding>
            <binding name="security">
                <security mode="Transport">
                    <transport clientCredentialType="Basic"/>
                </security>
            </binding>
        </basicHttpBinding>
    </bindings>
    <behaviors>
        <serviceBehaviors>
            <behavior name="md">
      <serviceCredentials>
        <userNameAuthentication
          userNamePasswordValidationMode="Custom"
          customUserNamePasswordValidatorType="ClassLibrary1.CustomUserNameValidator, ClassLibrary1" />
      </serviceCredentials>
                <serviceMetadata httpsGetEnabled="true"/>
            </behavior>
        </serviceBehaviors>
    </behaviors>
</system.serviceModel>

ClassLibrary1.CustomUserNameValidato:

public class CustomUserNameValidator : System.IdentityModel.Selectors.UserNamePasswordValidator
    {
        public override void Validate(string userName, string password)
        {
            if (userName != "111" || password != "111")
            {

                throw new System.ServiceModel.FaultException("Unknown username or incorrect password");
            }
        }
    }

Клиент:

<system.serviceModel>
    <bindings>
        <basicHttpBinding>
            <binding name="BasicHttpBinding_IService" closeTimeout="00:01:00"
                openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"
                allowCookies="false" bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard"
                maxBufferSize="65536" maxBufferPoolSize="524288" maxReceivedMessageSize="65536"
                messageEncoding="Text" textEncoding="utf-8" transferMode="Buffered"
                useDefaultWebProxy="true">
                <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
                    maxBytesPerRead="4096" maxNameTableCharCount="16384" />
                <security mode="Transport">
                    <transport clientCredentialType="Basic" proxyCredentialType="Basic" realm="">
                        <extendedProtectionPolicy policyEnforcement="Never" />
                    </transport>
                    <message clientCredentialType="UserName" algorithmSuite="Default" />
                </security>
            </binding>
        </basicHttpBinding>
    </bindings>
    <client>
        <endpoint address="https://pc:8080/Service.svc/SslService" binding="basicHttpBinding"
            bindingConfiguration="BasicHttpBinding_IService" contract="ServiceReference1.IService"
            name="BasicHttpBinding_IService" />
    </client>
</system.serviceModel>

ServiceReference1.ServiceClient s = new WindowsFormsApplication1.ServiceReference1.ServiceClient();

s.ClientCredentials.UserName.UserName = "111";
s.ClientCredentials.UserName.UserName = "111";
MessageBox.Show(s.GetData(3)); // <---- ERROR

HTTP-запрос не авторизован с помощью схемы аутентификации клиента «Basic». Заголовок аутентификации, полученный от сервера, был 'Basic realm = "pc"'.

Ответы [ 5 ]

12 голосов
/ 14 апреля 2016

Я создал такого клиента:

using (var client = new Client())
    {

    client.ClientCredentials.UserName.UserName = <username>;
    client.ClientCredentials.UserName.Password = **<WRONG_PASSWORD>**;
...
    }

Раздел безопасности моей привязки выглядел так:

          <security mode="Transport">
            <transport clientCredentialType="Basic" proxyCredentialType="Basic" realm="" />
          </security>

И я видел, как эта ошибка возвращалась. Как только я исправил пароль, все заработало.

10 голосов
/ 15 января 2010

Я предполагаю, что вы размещаете свой сервисный хост в IIS. Тогда проблема заключается в том, что IIS перехватывает запрос https и выполняет проверку подлинности на уровне IIS до того, как инфраструктура WCF и ваш пользовательский валидатор получит шанс.

В вашем примере IIS фактически будет искать локального пользователя «111» с паролем «111» на сервере, на котором работает IIS. Попробуйте создать этого пользователя на сервере, и вы, вероятно, получите другой результат.

Одним из решений является размещение вашего хоста службы WCF где-нибудь еще, например в службе Windows. Другое решение - изменить схему безопасности на TransportWithMessageCredential. Наконец, вы можете проверить этот модуль OSS http: Настраиваемая базовая аутентификация для IIS - похоже, нам нужно.

3 голосов
/ 21 декабря 2009

Попробуйте отправить имя пользователя и пароль не в http с обычной аутентификацией (это может смутить IIS), а только в заголовках мыльных сообщений по следующей схеме:

<binding name="...">
        <security mode="TransportWithMessageCredential" >
           <message clientCredentialType="UserName" />
        </security>
</binding>

Как использовать транспортную безопасность и учетные данные сообщения

Может быть, вам также нужно дополнительно указать <transport clientCredentialType="None">

1 голос
/ 16 октября 2013

Я разместил ответ здесь: Невозможно вызвать веб-сервис с базовой аутентификацией с использованием WCF транспорт clientcredentialType это TransportCredentialOnly

1 голос
/ 20 декабря 2009

Похоже, вы задали имя пользователя дважды вместо имени пользователя и пароля.

Если у вас есть базовая аутентификация, и вы не отправляете имя пользователя и пароль вместе с запросом, вы получаете ответ на запрос.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...