WCF:找不到我在web.config中指定的自定义验证器 - customUserNamePasswordValidatorType - - 无法加载文件或程序集... - 帮助?

ElH*_*aix 4 wcf customvalidator

所以我基本上已经通过HTTPS使用自定义身份验证使用wsHttpBindings和我的WCF服务运行了所有内容.

我遇到的问题是customUserNamePasswordValidatorType:

  <serviceCredentials>
    <!-- Use our own custom validation -->
    <userNameAuthentication userNamePasswordValidationMode="Custom"
                            customUserNamePasswordValidatorType="CustomValidator.CustomUserNameValidator, CustomValidator"/>
  </serviceCredentials>
Run Code Online (Sandbox Code Playgroud)

按照此处的说明,我也创建了自定义类:

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


            if (!AuthenticateUser(userName, password))
                throw new SecurityTokenValidationException("Invalid Credentials");
Run Code Online (Sandbox Code Playgroud)

错误是" 无法加载文件或程序集'CustomValidator'或其依赖项之一.系统无法找到指定的文件. ",并引用customUserNamePasswordValidatorType的尾端 - "...,CustomValidator".

我不认为在我自己的命名空间和类中使用自定义验证器是一个问题,但我看不出还有什么可以使它工作.

我在开始时尝试使用/不使用命名空间,交换等等 - 没有.

希望另一双眼睛可以选择这个.

谢谢.

编辑system.serviceModel

  <system.serviceModel>
    <bindings>

      <!-- wsHttpBinding -->
      <wsHttpBinding>
        <binding name="wsHttpEndpointBinding">
          <security mode="TransportWithMessageCredential">
            <transport clientCredentialType="None" />
            <message clientCredentialType="UserName" />
          </security>
        </binding>
      </wsHttpBinding>

      <!-- webHttpBinding -->
      <webHttpBinding>
        <binding name="wsHttps" >
          <security mode="Transport"/>
        </binding>
      </webHttpBinding>

      <!-- Basic binding -->
      <basicHttpBinding>
        <binding name="TransportSecurity">
          <security mode="Transport">
            <message clientCredentialType="UserName"/>
            <!-- transport clientCredentialType="None"/-->
          </security>
        </binding>
      </basicHttpBinding>

      <!-- customBinding>
        <binding name="WebHttpBinding_IService">
          textMessageEncoding maxReadPoolSize="64" maxWritePoolSize="16"
              messageVersion="Soap12" writeEncoding="utf-8">
            <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
                maxBytesPerRead="4096" maxNameTableCharCount="16384" />
          </textMessageEncoding>
          <httpsTransport manualAddressing="false"/>
        </binding>
      </customBinding -->
      <!-- Another custom binding -->
      <customBinding>
        <binding name="CustomMapper">
          <webMessageEncoding  webContentTypeMapperType=
                 "IndexingService.CustomContentTypeMapper, IndexingService" />
          <httpTransport manualAddressing="true" />
        </binding>
      </customBinding>
    </bindings>
    <serviceHostingEnvironment aspNetCompatibilityEnabled="false" />
    <services>
      <service behaviorConfiguration="ServiceBehavior" name="Service">




        <!-- Service Endpoints -->
        <!-- since we're hosting in IIS, baseAddress is not required 
        <host>
          <baseAddresses>
            <add baseAddress="https://mysslserver.com/Service.svc"/>
          </baseAddresses>
        </host>
        -->
        <endpoint address="https://mysslserver.com/Service.svc"
                  binding="wsHttpBinding"
                  bindingConfiguration="wsHttpEndpointBinding" 
                  contract="IService"
                  name="wsHttpEndpoint">
          <!-- 
              Upon deployment, the following identity element should be removed or replaced to reflect the 
              identity under which the deployed service runs.  If removed, WCF will infer an appropriate identity 
              automatically.
          -->
          <!--identity>
            <dns value="https://mysslserver.com"/>
          </identity-->
        </endpoint>

        <!-- endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/ -->
      </service>
    </services>
    <behaviors>

      <endpointBehaviors>
        <behavior name="webBehavior">
          <webHttp />
        </behavior>
      </endpointBehaviors>

      <serviceBehaviors>
        <behavior name="ServiceBehavior">
          <!-- Setup Security/Error Auditing -->
          <serviceSecurityAudit auditLogLocation="Application"
                suppressAuditFailure="false"
                serviceAuthorizationAuditLevel="Failure"
                messageAuthenticationAuditLevel="Failure" />

          <serviceMetadata httpGetEnabled="false" httpsGetEnabled="true"
                           httpsGetUrl="https://mysslserver.com/Service.svc"/>
          <serviceDebug includeExceptionDetailInFaults="false" />
          <serviceCredentials>
            <!-- Use our own custom validation -->
            <userNameAuthentication userNamePasswordValidationMode="Custom"
                                    customUserNamePasswordValidatorType="CustomValidator.CustomUserNameValidator, CustomValidator"/>
          </serviceCredentials>
        </behavior>
      </serviceBehaviors>

      <!-- serviceBehaviors>
        <behavior name="ServiceBehavior">
        <serviceMetadata httpsGetEnabled="true" 
                           httpsGetUrl="https://mysslserver.com/Service.svc" />
          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"/>
        </behavior-->
    </behaviors>
  </system.serviceModel>
Run Code Online (Sandbox Code Playgroud)

ElH*_*aix 14

我决定给它另一个刺,并且不喜欢在另一个lib中使用我的自定义验证器.

所以我在App_Code中创建了一个新类,然后继续...

以下是实际修复它的内容,

="CustomValidator.CustomUserNameValidator, App_Code"
Run Code Online (Sandbox Code Playgroud)

  • 这样的事情就是为什么我更喜欢'Convention over Configuration'..NET中的奥术配置设置有一天会让我进入心理病房. (5认同)
  • +1谢谢你,花了一段时间盯着那个试图弄清楚要选择哪个程序集:) (2认同)

And*_*son 9

当您使用值引用自定义验证器时

="CustomValidator.CustomUserNameValidator, CustomValidator"
Run Code Online (Sandbox Code Playgroud)

第一个值是类型名称,第二个值是要在其中查找类型的程序集的名称.所以我建议你的第一个例子,你的服务实际上是在其他程序集中,比如MyService.在这种情况下,你确实需要你的配置文件说

="CustomValidator.CustomUserNameValidator, MyService"
Run Code Online (Sandbox Code Playgroud)

我怀疑当你为验证器创建了新的类库时,你已经调用了你的项目CustomValidator(它将输出一个名为CustomValidator.dll的程序集),因此现在你的配置将起作用(即它与一个单独的类库 - 它恰好发生在web.config中的程序集引用的命名现在有效)