使用自定义UserNamePasswordValidator通过HTTPS进行WCF服务 - 如何处理空白用户名和密码

时间:2016-01-26 22:17:28

标签: c# wcf authentication https

我有一个WCF服务,它是一个HTTPS REST API,它公开了一些WebGet方法。我通过HTTPS使用传输级安全性。这一切都很好。我实现了自定义UserNamePasswordValidator,根据MSDN文档覆盖了Validate方法。

    public override void Validate(string userName, string password)
    {
        WebFaultException rejectEx = new WebFaultException(HttpStatusCode.Unauthorized);
        rejectEx.Data.Add("HttpStatusCode", rejectEx.StatusCode);

        if (null == userName || null == password)
            throw rejectEx;

        if (userName == "someusername" && password == "somepassword") return;

        throw rejectEx;            
    }

仅通过HTTPS访问服务(禁用http),提示用户名和密码,留下一个或输入一个或两个错误导致提示返回,因为我扔了401。

我遇到的问题是,如果在访问服务时遗漏了用户名和密码,则永远不会调用Validate。我需要能够处理这个并向浏览器/客户端返回一个信息性错误,甚至只返回401。

调试显示,在省略用户名和密码时,永远不会触发Validate。这意味着在浏览器中,您最终会得到一个空白页面并且没有错误。

如何处理这种情况并将响应返回给客户端再次提示凭据?

修改以包含配置信息:

<behaviors>
  <serviceBehaviors>
    <behavior name="RESTEndpointBehaviour">
      <serviceMetadata httpsGetEnabled="true" httpGetEnabled="false" />
      <serviceDebug includeExceptionDetailInFaults="false" />
      <serviceCredentials>
        <userNameAuthentication userNamePasswordValidationMode="Custom"
                                customUserNamePasswordValidatorType="MyAPI.CustomAuthenticator, MyAPI"
                                />
      </serviceCredentials>
    </behavior>
  </serviceBehaviors>
</behaviors>

<services>
  <service behaviorConfiguration="RESTEndpointBehaviour" name="MyAPI.RestService">
    <endpoint binding="webHttpBinding" bindingConfiguration="BasicHttpSSLBinding"
        contract="MyAPI.IRestService" />
    <endpoint address="mex" binding="mexHttpsBinding" contract="IMetadataExchange" />
    <host>
      <baseAddresses>
        <add baseAddress="https://localhost:443" />
      </baseAddresses>
    </host>
  </service>
</services>

<bindings>
  <webHttpBinding>
    <binding name="BasicHttpSSLBinding">
      <security mode="Transport">
        <transport clientCredentialType="Basic"/>
      </security>
    </binding>
  </webHttpBinding>
</bindings>

1 个答案:

答案 0 :(得分:0)

我最终通过实施serviceAuthorization来解决这个难题。根据下面的博客文章,通过一些调整来匹配我的应用程序。

http://www.allenconway.net/2012/07/using-basic-authentication-in-rest.html