Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

The HTTP request is unauthorized with client authentication scheme 'Basic'. The authentication header received from the server was 'Basic realm="pc"'

Tags:

wcf

Server:

<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");
            }
        }
    }

Client:

<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

The HTTP request is unauthorized with client authentication scheme 'Basic'. The authentication header received from the server was 'Basic realm="pc"'.

like image 796
RendeRR Avatar asked Dec 19 '09 00:12

RendeRR


5 Answers

I had created a client like this:

using (var client = new Client())
    {

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

The security section of my binding looked like this:

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

And I saw this error come back. Once I corrected the password, everything worked.

like image 77
Nick McKeel Avatar answered Nov 14 '22 11:11

Nick McKeel


I'm assuming you are hosting your servicehost on the IIS. Then the problem is that the IIS intercepts the https request and performs IIS-level authentication before the WCF framework and your custom validator has a chance to kick in.

In your example, the IIS will actually look for a local user '111' with password '111' on the server running the IIS. Try creating this user on the server, and you will probably get a different result.

One solution is to host your WCF servicehost somewhere else, for example in a Windows Service. Another solution is to change your security scheme to TransportWithMessageCredential. Finally, you could check this OSS http module out: Custom Basic Authentication for IIS - seems to do the trick we need.

like image 45
peter_raven Avatar answered Nov 14 '22 11:11

peter_raven


Try to send username and password not in http with basic authentication (this can embarrass IIS), but only in soap-message headers with following scheme:

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

How to: Use Transport Security and Message Credentials

Maybe you also need to additionally specify <transport clientCredentialType="None">

like image 43
Anon 806 Avatar answered Nov 14 '22 12:11

Anon 806


I posted an answer here: Can not call web service with basic authentication using WCF transport clientcredentialType is TransportCredentialOnly

like image 3
jaxxbo Avatar answered Nov 14 '22 13:11

jaxxbo


Looks like you set the user name twice instead of the user name and password.

When you have basic authentication and you do not send the username and password with the request you get a challenge response back.

like image 1
Shiraz Bhaiji Avatar answered Nov 14 '22 12:11

Shiraz Bhaiji