未调用自定义UserNamePasswordValidator

问题描述 投票:3回答:2

我正在尝试使用BasicHttpBinding和使用用户名/密码进行身份验证来设置WCF Web服务。我做了自定义身份验证类。但是,它永远不会被调用(通过调试验证)。这是我的web.config:

  <system.serviceModel>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
<behaviors>
  <serviceBehaviors>
    <behavior>
      <serviceCredentials>
        <userNameAuthentication userNamePasswordValidationMode="Custom" customUserNamePasswordValidatorType="Compareware_WebApp.webservices.AuthenticationValidator, Compareware_WebApp" />
      </serviceCredentials>
      <serviceMetadata httpGetEnabled="true" httpsGetEnabled="true" />
      <serviceDebug includeExceptionDetailInFaults="false" />
    </behavior>
  </serviceBehaviors>
</behaviors>
<bindings>
  <basicHttpBinding>
    <binding name="BasicHttpBinding">
      <security mode="TransportCredentialOnly">
        <message clientCredentialType="UserName" />
      </security>
    </binding>
  </basicHttpBinding>
</bindings>
<services>
  <service name="Compareware_WebApp.webservices.Accounts">
    <endpoint address="/webservices/Accounts.svc" binding="basicHttpBinding"
      bindingConfiguration="BasicHttpBinding" name="BasicEndpoint"
      contract="Compareware_WebApp.webservices.IAccounts" />
  </service>
</services>
<client />

这是我的身份验证类:

namespace Compareware_WebApp.webservices

{

public class AuthenticationValidator : UserNamePasswordValidator
{
    public override void Validate(string userName, string password)
    {
        if (null == userName || null == password)
        {
            throw new ArgumentNullException();
        }

        if (!Membership.ValidateUser(userName, password))
        {
            // This throws an informative fault to the client.
            throw new FaultException("Unknown Username or Incorrect Password");
        }
    }
}

}

我究竟做错了什么?

wcf basic-authentication
2个回答
4
投票

我也坚持这个问题,我得到了解决方案。如果你想调用ValidateUserNamePasswordValidator方法那么,你必须要使用TransportWithMessageCredential安全性。

注意:您必须必须在IIS服务器上托管WCF服务,并且必须为您的网站启用SSL,否则它将无法运行。如果我们使用TransportWithMessageCredential而不是我们为我们的网站启用SSL。

WCF服务器Web.config文件

<?xml version="1.0"?>
<configuration>
  <startup>
    <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5"/>
  </startup>
  <system.serviceModel>
    <bindings>
      <wsHttpBinding>
        <binding name="wsHttp">
          <security mode="TransportWithMessageCredential">
            <message clientCredentialType="UserName"/>
          </security>
        </binding>
      </wsHttpBinding>
    </bindings>
    <services>
      <service name="TransportWithMessageCredential.Service1" behaviorConfiguration="wsHttpBehavior">
        <endpoint address="" binding="wsHttpBinding" bindingConfiguration="wsHttp" contract="TransportWithMessageCredential.IService1">
          <identity>
            <dns value="localhost"/>
          </identity>
        </endpoint>
        <host>
          <baseAddresses>
            <add baseAddress="https://localhost:8080/WCFDemo"/>
          </baseAddresses>
        </host>
      </service>
    </services>
    <behaviors>
      <serviceBehaviors>
        <behavior name="wsHttpBehavior">
          <serviceMetadata httpGetEnabled="true" httpsGetEnabled="true"/>
          <serviceDebug includeExceptionDetailInFaults="false"/>
          <serviceCredentials>
            <userNameAuthentication userNamePasswordValidationMode="Custom" customUserNamePasswordValidatorType="TransportWithMessageCredential.ServiceAuthanticator, TransportWithMessageCredential"/>
          </serviceCredentials>
        </behavior>
      </serviceBehaviors>
    </behaviors>
  </system.serviceModel>
  <system.web>
    <compilation debug="true"/>
  </system.web>
</configuration>

服务验证类

 public class ServiceAuthanticator : UserNamePasswordValidator
    {
        /// <summary>
        /// 
        /// </summary>
        /// <param name="userName"></param>
        /// <param name="password"></param>
        public override void Validate(string userName, string password)
        {
            if (String.IsNullOrEmpty(userName) || String.IsNullOrEmpty(password))
            {
                throw new FaultException("Please, Provide the username and password!!!");
            }

            if (userName != "abc" || password != "abc")
            {
                throw new FaultException("Sorry, Invalid username or password!!!");
            }
        }
    }

WCF客户端app.config文件

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <startup> 
        <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
    </startup>
    <system.serviceModel>
        <bindings>
            <wsHttpBinding>
                <binding name="WSHttpBinding_IService1">
                    <security mode="TransportWithMessageCredential">
                        <transport clientCredentialType="None" />
                        <message clientCredentialType="UserName" />
                    </security>
                </binding>
            </wsHttpBinding>
        </bindings>
        <client>
            <endpoint address="https://kalpesh-pc/WCFAuth/Service1.svc" binding="wsHttpBinding"
                bindingConfiguration="WSHttpBinding_IService1" contract="ServiceReference1.IService1"
                name="WSHttpBinding_IService1">
                <identity>
                    <dns value="localhost" />
                </identity>
            </endpoint>
        </client>
    </system.serviceModel>
</configuration>

客户端程序调用WCF服务

try
{
    Service1Client objClient = new Service1Client();
    objClient.ClientCredentials.UserName.UserName = "abc";
    objClient.ClientCredentials.UserName.Password = "abc";

    objClient.Open();
    string strData = objClient.GetData(10);
}
catch (FaultException ex)
{
    Console.WriteLine(ex.Message);
}
catch (Exception ex)
{
    Console.WriteLine(ex.Message);
}

Console.ReadKey();

快乐编码......

:)


0
投票

据我所知,传输需要HTTPS来加密凭据,并在没有SSL时抛出异常。 TransportCredentialOnly将以纯文本和未加密的方式发送凭据,建议仅用于测试。因此,您的凭据将通过传输发送。所以<Transport>标签必须调整,而不是<Message>

以下适用于我:

<security mode="TransportCredentialOnly">
    <transport clientCredentialType="Basic"/>
</security>
© www.soinside.com 2019 - 2024. All rights reserved.