wcf - 未调用自定义 UserNamePasswordValidator

标签 wcf basic-authentication

我正在尝试使用用户名/密码设置带有 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");
        }
    }
}

}

我究竟做错了什么?

最佳答案

我也遇到了这个问题,我得到了解决方案。如果要调用 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();

快乐编码...

:)

关于wcf - 未调用自定义 UserNamePasswordValidator,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37434663/

相关文章:

wcf - DTO 在项目中的物理位置

node.js - REST API 的基本身份验证的两因素身份验证?

browser - 如何使用浏览器发送授权 header

http - 浏览器未将在深层 URL 上设置的 `Authorization` header 发送到根 URL

c# - WCF 使用匿名方法关闭连接

web-services - Azure 中的简单文件生成器服务?

wcf - 消费服务: The type name ‘AAA' does not exist in the type ‘YYY.YYY’ 时出错

c# - 用 C# 中更安全的选项替换 MarshalByRefObject

javascript - 在 img 标签中显示 mjpeg 的替代方案(使用基本身份验证)

java - jetty 嵌入式: Using CORS + Basic authentication (ConstraintSecurityHandler)