I am using a CustomUserNamePasswordValidator for my WCF web service. However, i am trying to add a IsAlive operation, which should be able to be called from clients, even when not authenticated.
For example, i want to be able to do a check, if a service is online and accessible on startup, so i can notify the user on missing inet connection or a not available service (due to maintenance).
I have code for all this already in place. What i am missing is how i can access the operation without passing a username and password.
I could probably just add a second service which allows anon access, but i'd really prefer to use the existing service.
The Validator is implemented like this (i ommited the actual checking code):
public sealed class MyCredentialValidator : UserNamePasswordValidator
{
    public MyCredentialValidator ()
    {
    }
    public override void Validate(string userName, string password)
    {
        Debug.WriteLine("MyCredentialValidator : Validate called.");
        // do some checks
        var isValid = CheckCredentials(userName, password)
        if(!isValid)
        {
            throw new FaultException(...);
        }
    }
}
It is registered in the web.config like so:
<system.serviceModel>
    <behaviors>
        <serviceBehaviors>
            <behavior name="SecureBehavior">
                <serviceMetadata httpsGetEnabled="false"/>
                <serviceDebug includeExceptionDetailInFaults="true"/>
                <serviceCredentials>
                    <userNameAuthentication userNamePasswordValidationMode="Custom" customUserNamePasswordValidatorType="MyCredentialValidator,..."/>
                </serviceCredentials>
            </behavior>
        </serviceBehaviors>         
    </behaviors>
    <serviceHostingEnvironment multipleSiteBindingsEnabled="true"/>
    <bindings>
        <wsHttpBinding>
            <binding name="SecureBinding" closeTimeout="00:10:00" openTimeout="00:10:00" receiveTimeout="00:10:00" sendTimeout="00:10:00" maxReceivedMessageSize="2147483647">
                <security mode="TransportWithMessageCredential">
                    <message clientCredentialType="UserName"/>
                </security>
                <readerQuotas maxArrayLength="2147483647" maxBytesPerRead="2147483647" maxStringContentLength="2147483647"/>
            </binding>
        </wsHttpBinding>
    </bindings>
    <services>
        <service name="my service" behaviorConfiguration="SecureBehavior">
            <endpoint address="" binding="wsHttpBinding" contract="my contract" bindingConfiguration="SecureBinding">
                <identity>
                    <dns value="localhost"/>
                </identity>
            </endpoint>
            <endpoint address="mex" binding="mexHttpsBinding" contract="IMetadataExchange"/>
        </service>
    </services>
</system.serviceModel>
client side configuration:
<system.serviceModel>
<bindings>
    <wsHttpBinding>
        <binding name="SecureBinding"
                 closeTimeout="00:10:00"
                 openTimeout="00:10:00"
                 receiveTimeout="00:10:00"
                 sendTimeout="00:10:00"
                 maxReceivedMessageSize="2147483647">
            <security mode="TransportWithMessageCredential">
                <message clientCredentialType="UserName"/>
            </security>
            <readerQuotas maxArrayLength="2147483647"
                          maxBytesPerRead="2147483647"
                          maxStringContentLength="2147483647"/>
        </binding>
    </wsHttpBinding>
</bindings>
<client>
    <endpoint address="https://my service url"
              contract="my contract"
              binding="wsHttpBinding"
              bindingConfiguration="SecureBinding"
              name="secure" />
</client>
</system.serviceModel>
client side wcf call code:
var cf = new ChannelFactory<my contract>("secure");
using (IClientChannel channel = (IClientChannel)cf.CreateChannel())
{
    channel.OperationTimeout = TimeSpan.FromSeconds(3);
    bool success = false;
    try
    {
        channel.Open();
        result = ((my contract)channel).IsAlive();
        channel.Close();
        success = true;
    }
    finally
    {
        if (!success)
        {
            channel.Abort();
        }
    }
}
