WCF: не удается найти пользовательский валидатор, указанный в web.config-customUserNamePasswordValidatorType - - не удалось загрузить файл или сборку ... - help?



Таким образом, у меня в основном все готово и работает с wsHttpBindings и моей службой WCF, использующей пользовательскую аутентификацию по HTTPS.



Проблема у меня с customUserNamePasswordValidatorType:



  <serviceCredentials>
<!-- Use our own custom validation -->
<userNameAuthentication userNamePasswordValidationMode="Custom"
customUserNamePasswordValidatorType="CustomValidator.CustomUserNameValidator, CustomValidator"/>
</serviceCredentials>


Следующие направления найдены здесь я также создал свой пользовательский класс:



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");


Ошибка " не удалось загрузить файл или сборку 'CustomValidator' или одну из его зависимостей. Система не может найти указанный файл.", и ссылается на хвостовая часть customUserNamePasswordValidatorType - "..., CustomValidator".



Я не думал, что проблема в том, что мой пользовательский валидатор находится в своем собственном пространстве имен и классе, но я не вижу, что еще можно сделать, чтобы это сработало.



Я пробовал с / без пространства имен в начале, подкачки и т. д.-Ничего.



Надеясь, что другая пара глаз сможет это заметить.



Спасибо.



Править
система.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>
629   4  
wcf

4 ответов:

Я решил нанести ему еще один удар, и мне не понравилось, что мой пользовательский валидатор находится в другом lib.

Поэтому я создал новый класс В App_Code и приступил к нему...

Вот что на самом деле исправило его,

="CustomValidator.CustomUserNameValidator, App_Code"

При обращении к пользовательскому валидатору со значениями

="CustomValidator.CustomUserNameValidator, CustomValidator"

Первое значение-это имя типа, а второе-имя сборки. в котором нужно найти типаж. Поэтому я бы предположил, что в вашем первом случае ваша служба фактически находится в какой-то другой сборке, такой как MyService В этом случае вам действительно нужен был ваш конфигурационный файл, чтобы сказать

="CustomValidator.CustomUserNameValidator, MyService"

Я подозреваю, что когда вы создадите свою новую библиотеку классов для вашего валидатор, вы вызвали свой проект CustomValidator (который будет выведите сборку с именем CustomValidator.dll), и следовательно теперь ваш config будет работать (то есть это не имеет ничего общего с тем, чтобы быть в отдельном библиотека классов-это просто случается, что имя вашей сборки ссылка в интернете.config теперь действителен)

Кажется немного странным, но решение состояло в том, чтобы создать отдельную библиотеку классов и сделать ссылку на ее DLL в моей службе WCF.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IdentityModel.Selectors;
using System.IdentityModel.Tokens;
using System.ServiceModel;

/// <summary>
/// Summary description for CustomUsernamePasswordValidator
/// </summary>
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");
            else
            {
                // do nothing - they're good
            }
        }

        public bool AuthenticateUser(string userName, string password)
        {
            if (userName != "userbill" || password != "passwordbill")
            {
                return false;
            }
            else
            {
                return true;
            }
        }
    }
}

Затем я добавил ссылку на систему.IdentityModel и система.Модель обслуживания.

Раздел serviceCredentials для службы WCF теперь изменен на следующий:

<serviceCredentials>
    <!-- Use our own custom validation -->
    <userNameAuthentication userNamePasswordValidationMode="Custom"
                            customUserNamePasswordValidatorType="CustomValidator.CustomUserNameValidator, CustomValidator"/>
</serviceCredentials>

Надеюсь, что это кому-то поможет.

Я попытался сделать это с неверными учетными данными и ожидал увидеть сообщение "неверные учетные данные". Вместо этого я получаю "на по крайней мере один маркер безопасности в сообщении не может быть проверен."

Кроме того, что эта штука наконец-то заработала!

Просто читая это, поскольку это было полезно для POC, я должен был быстро идти. В ответ наELHaix выше...это должно работать, чтобы гарантировать, что ваша описательная пользовательская ошибка будет возвращена обратно клиенту:

using System.ServiceModel
...    
throw new FaultException("Invalid Credentials - Custom Error");

Comments

    Ничего не найдено.