2012-03-22 5 views
1

Я создал тестовое приложение WCF, в котором я пытаюсь заставить Authentication работать, но он просто запускает мой метод и не просит меня войти/пройти проверку подлинности. Ниже фрагменты кода в моем web.config в моем WCF приложения:WCF Аутентификация не запрашивает учетные данные

<bindings> 
     <wsHttpBinding> 
      <binding name="Binding1"> 
       <security mode="Message"> 
        <message clientCredentialType="UserName" /> 
       </security> 
      </binding> 
     </wsHttpBinding> 
</bindings> 

<serviceCredentials> 
     <userNameAuthentication userNamePasswordValidationMode="Custom" customUserNamePasswordValidatorType="MyAPI.Authorization, App_Code" /> 
</serviceCredentials> 

Мой класс Авторизация:

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

      if (!(userName == "test1" && password == "1tset") && !(userName == "test2" && password == "2tset")) 
      { 
       // This throws an informative fault to the client. 
       throw new FaultException("Unknown Username or Incorrect Password"); 
       // When you do not want to throw an infomative fault to the client, 
       // throw the following exception. 
       // throw new SecurityTokenException("Unknown Username or Incorrect Password"); 
      } 
     } 
    } 

Мои Service.svc.cs Класс

public string Hello(string message) 
{ 
    return "You typed: " + message; 
} 

я должен поместите некоторый атрибут выше этого метода, чтобы требовать аутентификации или выше класса?

Я тогда создал тестовое приложение консоли, вот код:

public static Test.Service1Client client = new Test.Service1Client(); 
     static void Main(string[] args) 
     { 
      Console.WriteLine(client.Hello("hello")); 
      Console.ReadLine(); 
     } 

Это просто выводит «Введено: привет» без запроса аутентификации. Вот отрывки из моего app.config:

<system.serviceModel> 
     <bindings> 
      <basicHttpBinding> 
       <binding name="BasicHttpBinding_IService1" closeTimeout="00:01:00" 
        openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00" 
        allowCookies="false" bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard" 
        maxBufferSize="65536" maxBufferPoolSize="524288" maxReceivedMessageSize="65536" 
        messageEncoding="Text" textEncoding="utf-8" transferMode="Buffered" 
        useDefaultWebProxy="true"> 
        <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384" 
         maxBytesPerRead="4096" maxNameTableCharCount="16384" /> 
        <security mode="None"> 
         <transport clientCredentialType="None" proxyCredentialType="None" 
          realm="" /> 
         <message clientCredentialType="UserName" algorithmSuite="Default" /> 
        </security> 
       </binding> 
      </basicHttpBinding> 
     </bindings> 
     <client> 
      <endpoint address="http://MyServer/Service1.svc" binding="basicHttpBinding" 
       bindingConfiguration="BasicHttpBinding_IService1" contract="Test.IService1" 
       name="BasicHttpBinding_IService1" /> 
     </client> 
    </system.serviceModel> 

Я бы ожидать, чтобы установить учетные данные для входа перед вызовом client.Hello("hello"), выполнив:

client.ClientCredentials.UserName.UserName = "test1"; 
client.ClientCredentials.UserName.Password = "1tset"; 

Но, очевидно, не

Редактировать
<?xml version="1.0"?> 
<configuration> 

    <system.web> 
     <compilation debug="true" targetFramework="4.0" /> 
    </system.web> 
    <system.serviceModel> 
     <bindings> 
      <wsHttpBinding> 
       <binding name="Binding1"> 
        <security mode="Message"> 
         <message clientCredentialType="UserName" /> 
        </security> 
       </binding> 
      </wsHttpBinding> 
     </bindings> 
     <behaviors> 
      <serviceBehaviors> 
       <behavior> 
        <serviceCredentials> 
    <userNameAuthentication userNamePasswordValidationMode="Custom" customUserNamePasswordValidatorType="MyAPI.Authorization, App_Code" /> 
</serviceCredentials> 
        <!-- 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="false"/> 
       </behavior> 
      </serviceBehaviors> 
     </behaviors> 
     <serviceHostingEnvironment multipleSiteBindingsEnabled="true" /> 
    </system.serviceModel> 
    <system.webServer> 
     <modules runAllManagedModulesForAllRequests="true"/> 
    </system.webServer> 

</configuration> 
+0

Обычно клиент, такой как браузер, запрашивает учетные данные. Ваше тестовое консольное приложение не будет запрашивать, потому что вы не закодировали его таким образом. Сказано, что вызов службы должен был сбой, если вы не предоставили учетные данные. Проверьте, связали ли вы службу с ожиданием Binding1 в конфигурации сервера. – VinayC

+0

@VinayC - Где я вижу это? См. Мое редактирование, он содержит весь мой файл web.config из моей службы. – CallumVass

ответ

0

Похоже, вы используете неправильные привязки, клиент использует BasicHttp Связывание, когда вы определили WsHttpBinding на сервере.

0

WCF/IIS будет волшебным образом подключать сервисы, которые у вас есть, без необходимости настройки (не помню названия этой функции небрежно ...). Тем не менее, вы определяете какую-то настраиваемую конфигурацию привязки - все в порядке, но вам нужно сказать, что ваша служба использует это.

Вы должны добавить <service> элемент конфигурации вы сервера, что-то вроде:

<system.serviceModel> 
    ... 
    <services> 
     <service name="FullClassNameOfYourService"> 
     <endpoint binding="wsHttpBinding" 
        bindingConfiguration="Binding1" 
        contract="FullClassNameOfYourServiceContract" /> 
     </service> 
    </services> 

Кроме того, тот факт, что ваш клиент конфигурации не содержит wsHttpBinding элемент предполагает, что HTTPS не включена для веб-сайта хостинг вашего сервиса.

+0

Теперь я получаю: Название контракта «MyAPI.IService1» не может быть найдено в списке контрактов, реализованных службой «Service1». – CallumVass

+0

Является ли значение атрибута 'name' просто« Serivce1 »? Основываясь на вашем типе контракта, я думаю, что имя службы должно быть «MyAPI.Service1» - для имени класса также требуется пространство имен. –

+0

У меня есть этот набор: '<имя службы = "MyAPI.Service1"> <конечная точка привязки = "WsHttpBinding" bindingConfiguration = "Binding1" контракт = "MyAPI.IService1"/>' – CallumVass

0

Неправильная идентификация пользователя. customUserNamePasswordValidatorType должен иметь форму «[полная сборка + имя_файла], [namespace]». Я не могу сказать, что ваше пространство имен из вашего поста, но что-то вроде:

<userNameAuthentication userNamePasswordValidationMode="Custom" 
customUserNamePasswordValidatorType="MyNamespace.Authorization , MyNamespace" /> 

Как уже сказал, ваш клиент должен использовать тот же тип привязки для подключения к услуге.

Кроме того, на вашей стороне сервера установлен режим безопасности, но у вас есть транспорт и тег сообщения. В теге безопасности. Любые характеристики безопасности передачи и сообщений игнорируются, если вы выполняете «Нет» в качестве вашей безопасности. Другими словами, с режимом безопасности None, ваш учетный тип клиента не учитывается, и, следовательно, клиенты не должны аутентифицироваться.

+0

Я пробовал это, но он все время выдавал ошибку, поэтому я поместил свой класс авторизации внутри App_Code и использовал это, он сработал! Теперь я поставил тип безопасности на «Транспорт» и установил тот же тип привязки как на клиенте, так и на сервере (оба с использованием basicHttpbinding), но я получаю следующую ошибку: «Предоставленная схема URI« http »недействительна; ожидаемый «https». Имя параметра: via' – CallumVass

+0

«Ошибка» не очень помогает мне. Как вы знаете, что включение его в App_Code работает, если вы получаете другую ошибку? если он ищет https, это указывает на то, что вы указали безопасность уровня транспорта. –

+0

«ошибка», я имею в виду, что это ошибка, пока я не изменил ее, чтобы использовать App_Code, затем она «работала», то есть не выдавала ошибку, но это не проблема здесь – CallumVass

0

Вы используете WCF 4 с упрощенным конфигурационным файлом. Он имеет свои достоинства, но его отлаживать сложнее.Я подозреваю, что ваш пользовательский wshttpbinding не применяется. Попробуйте более подробное конфигурирование (например, wcf 3.5):

<system.serviceModel> 
    <bindings> 
     <wsHttpBinding> 
     <binding name="NewBinding0"> 
      <security mode="TransportWithMessageCredential"> 
      <message clientCredentialType="UserName" /> 
      </security> 
     </binding> 
     </wsHttpBinding> 
    </bindings> 
    <services> 
     <service behaviorConfiguration="WcfService6.Service1Behavior" 
     name="WcfService6.Service1"> 
     <endpoint address="" binding="wsHttpBinding" bindingConfiguration="NewBinding0" 
      contract="WcfService6.IService1"> 
      <identity> 
      <dns value="localhost" /> 
      </identity> 
     </endpoint> 
     <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" /> 
     </service> 
    </services> 
    <behaviors> 
     <serviceBehaviors> 
     <behavior name="WcfService6.Service1Behavior"> 
      <!-- 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="false"/> 
     </behavior> 
     </serviceBehaviors> 
    </behaviors> 
    </system.serviceModel> 
Смежные вопросы