WCF service authentication using iisexpress transport security and basic authentication always returning 401

httpmoduleiis-expresssslvisual studio 2010wcf

I have a WCF service configured to use Transport security and basic authentication.

The service is hosted in iiexpress withing vs2010.

I am able to connect from my client code but always receive:

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

And this has an inner exception of:

"The remote server returned an error: (401) Unauthorized."

Similar to Can not call web service with basic authentication using WCF although my client code already has the settings set out in the answer.

I also followed HTTP Basic Authentication against Non-Windows Accounts in IIS/ASP.NET (Part 3 – Adding WCF Support) and the previous blog to set up a Module and the IAuthorizationPolicy classes.

IISExpress is configed in classic mode with anonymous and windows authentication disabled and SSL enabled.

Client Config:

<system.serviceModel>
    <bindings>
      <basicHttpBinding>
        <binding name="NotificationHttpBinding">
          <security mode="Transport">
            <transport clientCredentialType="Basic" />
          </security>
        </binding>
      </basicHttpBinding>
    </bindings>
    <client>
      <endpoint address="https://localhost/NotificationService.svc"
         binding="basicHttpBinding" bindingConfiguration="NotificationHttpBinding"
         contract="NotificationPortType" name="BasicHttpBinding_NotificationPortType" />
    </client>
  </system.serviceModel>

Service Config:

<system.serviceModel>

    <serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />

    <services>
      <service name="Notification.NotificationService" behaviorConfiguration="NotificationServiceBehavior">
        <endpoint binding="basicHttpBinding" contract="NotificationPortType" bindingConfiguration="NotificationHttpBinding" >
        </endpoint>
       </service>
    </services>

    <behaviors>
      <serviceBehaviors>
        <behavior name="NotificationServiceBehavior">
          <serviceMetadata />
          <serviceDebug includeExceptionDetailInFaults="false"/>
          <serviceAuthorization>
            <authorizationPolicies>
              <add policyType="Notification.HttpContextIdentityPolicy, Notification" />
            </authorizationPolicies>
          </serviceAuthorization>
        </behavior>
      </serviceBehaviors>
    </behaviors>

    <bindings>
      <basicHttpBinding>
        <binding name="NotificationHttpBinding">
          <security mode="Transport">
            <transport clientCredentialType="Basic" />
          </security>

        </binding>
      </basicHttpBinding>
    </bindings>

  </system.serviceModel>


  <system.webServer>
    <modules runAllManagedModulesForAllRequests="true"/>
  </system.webServer>

  <system.web>

    <httpModules>
      <add name="CustomBasicAuthentication" type="Notification.CustomBasicAuthenticationModule, Notification"/>
    </httpModules>

    <membership defaultProvider="SampleProvider">
      <providers>
        <add name="SampleProvider"  type="Notification.HardcodedSecurityProviders, Notification" />
      </providers>
    </membership>

  </system.web>

Client Code is nothing major:

static void Main(string[] args)
        {
            ServicePointManager.ServerCertificateValidationCallback = (sender, certificate, chain, sslPolicyErrors) => { return true; };

            NotificationPortTypeClient client = new NotificationPortTypeClient("BasicHttpBinding_NotificationPortType");

            client.ClientCredentials.UserName.UserName = "Test";
            client.ClientCredentials.UserName.Password = "PWD";


            client.sendNotification(new NotificationRequest());
        }

Alternatively
If someone can show me an alternative of how to use IIS6 to host a service WCF which using basic http authentication while requiring SSL (https) I'll be happy with that!


UPDATE
Seems this was my culprit all along:
Avoid http 401 round trip

However, I found that my modules fired fine (in integrated mode) but I was then presented with a service error telling me that basic integration is required but not enabled on the host.

Opened up iisexpress applicationhost.config file and sure enough I found:

<section name="basicAuthentication" overrideModeDefault="Deny" />

followed by

<basicAuthentication enabled="false" />

further down

I've changed these to <section name="basicAuthentication" overrideModeDefault="Allow" />

and tried to enable in my web.config…no dice 🙁

Best Answer

You need to use WSHttpBinding.

There is a complete sample here.

Related Topic