7
Answers

Problem with a simple Wcf service authentication

Eric Bryan

Eric Bryan

9y
598
1
 

Hello everybody,

I have developp a Wcf sample project.

This sample works fine alone but when I want to add authentication to it, it fails.

I have set the diagnostic trace for this Wcf service but the messages I get are only :"Fail to open System.ServiceModel.ServiceHost", "System.ServiceModel.ServiceHost has generated errors" and "An error System.ServiceModel.ServiceHost has appened.

I have been based on a simple example I found on the net and I think I have reproduced it correctly.

Here is the web.config file for my Wcf service :

<?xml version="1.0" encoding="utf-8"?>
<configuration>

  <system.web>
    <compilation debug="true" targetFramework="4.0" />
  </system.web>

  <system.serviceModel>

    <bindings >
      <basicHttpBinding>
        <binding name="basicHttpServiceBinding">
          <security mode="TransportCredentialOnly">
            <transport clientCredentialType="Basic"/>
          </security>
        </binding>
      </basicHttpBinding>
    </bindings>

    <behaviors>
      <serviceBehaviors>
        <behavior name="customBehavior">
          <serviceMetadata httpGetEnabled="true" httpsGetEnabled="true" />
          <serviceDebug includeExceptionDetailInFaults="true" />
          <serviceCredentials>
            <userNameAuthentication
              userNamePasswordValidationMode="Custom"
              customUserNamePasswordValidatorType="WcfService1.UserAuthentication,WcfService1"/>
          </serviceCredentials>
        </behavior>
      </serviceBehaviors>
    </behaviors>

    <services>
      <service name="WcfService1.Service1" behaviorConfiguration="customBehavior"> 
        <endpoint address="http://localhost/TestServiceWCF/Service1.svc" binding="basicHttpBinding"
                  bindingConfiguration="basicHttpServiceBinding"
                  contract="WcfService1.IService1">
          <identity>
            <dns value="localhost" />
          </identity>
        </endpoint>
        <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
        <host>
          <baseAddresses>
            <add baseAddress="http://localhost/TestServiceWCF/" />
          </baseAddresses>
        </host>
      </service>
    </services>

    <diagnostics wmiProviderEnabled="true">
      <messageLogging
           logEntireMessage="true"
           logMalformedMessages="true"
           logMessagesAtServiceLevel="true"
           logMessagesAtTransportLevel="true"
           maxMessagesToLog="3000"
       />
    </diagnostics>
    <serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
    
  </system.serviceModel>

  <!-- log de wcf -->

  <system.diagnostics>
    <trace autoflush="true" indentsize="4" />
    <sources>
      <source name="System.ServiceModel"
              switchValue="All"
              propagateActivity="true" >
        <listeners>
          <add name="xml"/>
        </listeners>
      </source>
      <source name="System.ServiceModel.MessageLogging">
        <listeners>
          <add name="xml"/>
        </listeners>
      </source>
      <source name="myUserTraceSource"
              switchValue="Information, ActivityTracing, Warning, Error">
        <listeners>
          <add name="xml"/>
        </listeners>
      </source>
    </sources>
    <sharedListeners>
      <add name="xml"
           type="System.Diagnostics.XmlWriterTraceListener"
                 initializeData="E:\ldiep\Projets\Wcf\IIS_Logs\messages.svclog" />
    </sharedListeners>
  </system.diagnostics>
  
  <system.webServer>
    <modules runAllManagedModulesForAllRequests="true"/>
  </system.webServer>
  
</configuration>

Here is the App.config for my client application :

<?xml version="1.0" encoding="utf-8" ?>
<configuration>

  <system.serviceModel>
    <bindings>
      <basicHttpBinding>
        <binding name="DefaultBinding_IService1">
          <security mode="TransportCredentialOnly">
            <transport clientCredentialType="Basic"/>
          </security>
        </binding>
      </basicHttpBinding>
    </bindings>
    <client>

      <endpoint address="http://localhost/TestServiceWCF/Service1.svc"
                binding="basicHttpBinding" bindingConfiguration="DefaultBinding_IService1"
                contract="ServiceReference1.IService1"
                name="ServiceReference1" />
    </client>

  </system.serviceModel>

</configuration>

Here is the UserAuthentication.cs :

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.ServiceModel;
using System.IdentityModel.Selectors;

namespace WcfService1
//namespace Service
{
    public class UserAuthentication : UserNamePasswordValidator
    {
        public override void Validate(string userName, string password)
        {
            try
            {
                if (userName == "test" && password == "test123")
                {
                    Console.WriteLine("Authentic User");
                }
            }
            catch (Exception ex)
            {
                throw new FaultException("Unknown Username or Incorrect Password");
            }
        }
    }
}

And here is my call to the Wcf service :

 ServiceReference1.Service1Client serviceProxy = new ServiceReference1.Service1Client();
                serviceProxy.ClientCredentials.UserName.UserName = "test";
                serviceProxy.ClientCredentials.UserName.Password = "test123";

                string sReturned = serviceProxy.GetData(14);

Thank you very much in advance.

Eric.

Answers (7)