WCF无法在UserNamePasswordValidator中调用validate方法

时间:2014-03-25 07:41:57

标签: wcf wcf-security

我用一个教程来保护用户名和密码以及证书来保护wcf服务。 我使用 pluralsight的自我证书工具创建并安装了证书。并覆盖验证方法,该方法继承自 UserNamePasswordValidator 。证书安全性工作正常,但在服务调用期间不调用validate方法。无需提供用户名和密码即可访问服务 我读了很多关于它的文章,但是那里显示了相同的程序。我也读了关于同样问题的其他堆栈溢出问题,但我无法找到它的解决方案。

验证码

using System;
using System.IdentityModel.Selectors;
using System.ServiceModel;

namespace WcfSecure
{
    public class CredentialValidator : UserNamePasswordValidator
    {
        public override void Validate(string userName, string password)
        {
            if (userName == null && password == null)
                throw new ArgumentNullException();
            if (!(userName == "one" && password == "two"))
                throw new FaultException("Wrong Credentials!");
        }
    }
}

服务合同。

using System.ServiceModel;

namespace WcfSecure
{

    [ServiceContract]
    public interface ISecureWebService
    {
        [OperationContract]
        int SecureAdd(int x, int y);

        [OperationContract]
        int UnSecureService(int x, int y);
    }
}

服务代码

namespace WcfSecure
{
    public class SecureWebService : ISecureWebService
    {
        public int SecureAdd(int x, int y)
        {
            return x + y;
        }

        public int UnSecureService(int x, int y)
        {
            return x + y;
        }
    }
}

最重要的Web.config

<?xml version="1.0"?>
<configuration>

  <appSettings>
    <add key="aspnet:UseTaskFriendlySynchronizationContext" value="true" />
  </appSettings>


  <system.web>
    <compilation debug="true" targetFramework="4.5" />
    <httpRuntime targetFramework="4.5"/>
  </system.web>


  <system.serviceModel>

     <bindings>
      <wsHttpBinding>
        <binding name="SecureBinding">
          <security mode="Message">
            <message clientCredentialType="UserName" establishSecurityContext="true"/>
          </security>
        </binding>
      </wsHttpBinding>
    </bindings>

    <behaviors>
      <serviceBehaviors >
        <behavior name="CustomBehavior">
          <!-- To avoid disclosing metadata information, set the values below to false before deployment -->
          <serviceMetadata httpGetEnabled="true" httpsGetEnabled="true"/>
          <serviceDebug includeExceptionDetailInFaults="true"/>
          <serviceCredentials>
            <serviceCertificate findValue="SecureService"
                                storeLocation="LocalMachine"
                                storeName="My"
                                x509FindType="FindBySubjectName"/>
            <userNameAuthentication  userNamePasswordValidationMode="Custom" customUserNamePasswordValidatorType="WcfSecure.CredentialValidator, WcfSecure" />
          </serviceCredentials>
        </behavior>
      </serviceBehaviors>
    </behaviors>

    <services>
      <service behaviorConfiguration="CustomBehavior" name ="WcfSecure.SecureWebService">
        <endpoint address="" binding="wsHttpBinding" contract="WcfSecure.ISecureWebService"></endpoint>
        <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"></endpoint>
        <host>
          <baseAddresses>
            <add baseAddress="http://192.168.1.224:84/WcfSecure/SecureWebService"/>
          </baseAddresses>
        </host>
      </service>
    </services>

  </system.serviceModel>
  <system.webServer>
    <modules runAllManagedModulesForAllRequests="true"/>
    <!--
        To browse web app root directory during debugging, set the value below to true.
        Set to false before deployment to avoid disclosing web app folder information.
      -->
    <directoryBrowse enabled="true"/>
  </system.webServer>

</configuration>

1 个答案:

答案 0 :(得分:0)

a)我在客户端和服务器计算机上安装了我的证书

b)这是客户端配置文件的一部分

  <system.serviceModel>
    <bindings>
      <ws2007HttpBinding>
        <binding name="WS2007HttpBinding_MyAppWCFServices"
                 closeTimeout="00:00:30"
                 openTimeout="00:00:30"
                 receiveTimeout="00:00:30"
                 sendTimeout="00:05:00"
                 bypassProxyOnLocal="false"
                 transactionFlow="false"
                 hostNameComparisonMode="StrongWildcard"
                 maxBufferPoolSize="6000000"
                 maxReceivedMessageSize="6000000"
                 messageEncoding="Text"
                 textEncoding="utf-8"
                 useDefaultWebProxy="true"
                 allowCookies="false">
          <readerQuotas maxDepth="32" maxStringContentLength="2147483647" maxArrayLength="6000000" maxBytesPerRead="4096" maxNameTableCharCount="16384" />
          <reliableSession ordered="true" inactivityTimeout="00:10:00" enabled="false" />
          <security mode="Message">
            <transport realm="" />
            <message clientCredentialType="UserName" negotiateServiceCredential="false" />
          </security>
        </binding>
      </ws2007HttpBinding>
    </bindings>

    <behaviors>
      <endpointBehaviors>
        <behavior name="MyAppServiceBehaviour">
          <clientCredentials>
            <serviceCertificate>
              <authentication certificateValidationMode="None" revocationMode="NoCheck"/>
            </serviceCertificate>
          </clientCredentials>
        </behavior>
      </endpointBehaviors>
    </behaviors>

    <client>
      <endpoint address="http://servername:888/MyApp.WCF.Services/WorkFlowService.svc"
        binding="ws2007HttpBinding" bindingConfiguration="WS2007HttpBinding_MyAppWCFServices" behaviorConfiguration="MyAppServiceBehaviour"
        contract="MyApp.WCF.Services.IWorkFlowService" name="WorkFlowServiceEndpoint">
        <identity>
          <certificateReference  storeLocation="LocalMachine" storeName="My" x509FindType="FindByThumbprint" findValue="AF43F4486E52B225408B252C6479DBD6814FCE5B"/>
        </identity>
      </endpoint>
    </client>
</system.serviceModel>

c)这是服务器配置文件

的部分
<system.serviceModel>
    <bindings>
      <ws2007HttpBinding>
        <binding name="WS2007HttpBinding_MyAppWCFServices"
                 closeTimeout="00:00:30"
                 openTimeout="00:00:30"
                 receiveTimeout="00:01:00"
                 sendTimeout="00:10:00"
                 bypassProxyOnLocal="false"
                 transactionFlow="false"
                 hostNameComparisonMode="StrongWildcard"
                 maxBufferPoolSize="6000000"
                 maxReceivedMessageSize="6000000"
                 messageEncoding="Text"
                 textEncoding="utf-8"
                 useDefaultWebProxy="true"
                 allowCookies="false">
          <readerQuotas maxDepth="32" maxStringContentLength="2147483647" maxArrayLength="6000000" maxBytesPerRead="4096" maxNameTableCharCount="16384" />
          <reliableSession ordered="true" inactivityTimeout="00:10:00" enabled="false" />
          <security mode="Message">
            <transport realm="" />
            <message clientCredentialType="UserName" negotiateServiceCredential="false" />
          </security>
        </binding>
      </ws2007HttpBinding>
    </bindings>

    <serviceHostingEnvironment multipleSiteBindingsEnabled="true">
      <serviceActivations>
        <add relativeAddress="MyApp.WCF.Services/WorkflowService.svc" service="MyApp.WCF.Services.WorkFlowService" />
      </serviceActivations>
    </serviceHostingEnvironment>

    <behaviors>
      <serviceBehaviors>
        <behavior name="MyAppServiceBehaviour">
          <!-- To avoid disclosing metadata information, set the value below to false and remove the metadata endpoint above before deployment -->
          <serviceMetadata httpGetEnabled="true" />
          <!-- To receive exception details in faults for debugging purposes, set the value below to true.  Set to false before deployment to avoid disclosing exception information -->
          <serviceDebug includeExceptionDetailInFaults="true" />
          <serviceCredentials>
            <serviceCertificate storeLocation="LocalMachine" storeName="My" x509FindType="FindByThumbprint" findValue="AF43F4486E52B225408B252C6479DBD6814FCE5B" />
          </serviceCredentials>
        </behavior>
        <behavior name="ExposeMetaDataBehavior">
          <serviceMetadata httpGetEnabled="true" />
          <serviceDebug includeExceptionDetailInFaults="true" />
        </behavior>
      </serviceBehaviors>
    </behaviors>

    <services>
      <service behaviorConfiguration="MyAppServiceBehaviour" name="MyApp.WCF.Services.WorkFlowService">
        <endpoint address="" binding="ws2007HttpBinding" bindingConfiguration="WS2007HttpBinding_MyAppWCFServices" contract="MyApp.WCF.Services.IWorkFlowService" />
      </service>
    </services>
  </system.serviceModel>

希望这有帮助!