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>
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