禁用CustomUserNamePasswordValidator以执行特定操作

时间:2014-11-10 10:30:13

标签: wcf c#-4.0

我正在为我的WCF Web服务使用CustomUserNamePasswordValidator。但是,我正在尝试添加IsAlive操作,该操作应该能够从客户端调用,即使未经过身份验证也是如此。

例如,我希望能够检查,如果服务在线并且在启动时可访问,那么我可以通知用户缺少inet连接或不可用的服务(由于维护)。

我已经有了所有这些的代码。我缺少的是如何在不传递用户名和密码的情况下访问操作。

我可能只是添加了第二项允许匿名访问的服务,但我真的更喜欢使用现有服务。

验证器是这样实现的(我省略了实际的检查代码):

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(...);
        }
    }
}

它在web.config中注册如下:

<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>

客户端配置:

<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>

客户端wcf呼叫代码:

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

1 个答案:

答案 0 :(得分:0)

之前我做过类似的事情, 取决于您如何在wcf pipleline中集成自定义验证器, 你可以在你做实际验证之前,我猜它会返回真或假,你可以检查传入的URL或地址,看看它是否会进入你的IsAlive操作,如果是这样,你可以只是做一个早期的回报。

Wcf有几种方法可以检查客户端调用的操作。

为了更准确,我需要知道你是如何编写自定义验证器的,以及它集成的管道中的位置。

相关问题