Службы WCF показывают исключения при обеспечении сервиса с привязкой wshttpbinding и аутентификации имя пользователя


Я создал workflowservice в .net 4.0

Я пытаюсь защитить эту службу (WCF) и использовал следующую ссылку, чтобы увидеть, как это делается.

Я следовал инструкциям, однако, когда A определяет servicebehavior everthing работает нормально. Конфигурация выглядит следующим образом:

<behaviors>
      <serviceBehaviors>
        <behavior>
         <serviceCredentials name="ServiceBehavior">
            <userNameAuthentication userNamePasswordValidationMode="MembershipProvider"
              membershipProviderName="AspNetSqlMembershipProvider" />
          </serviceCredentials>
          <serviceMetadata httpGetEnabled="true" />
          <serviceDebug includeExceptionDetailInFaults="false" />
        </behavior>
      </serviceBehaviors>
    </behaviors>

Мои привязки задаются следующим образом:

<bindings>
      <wsHttpBinding>
        <binding name="CentralAdminBinding">
          <security mode="TransportWithMessageCredential">
            <transport clientCredentialType="None"/>
            <message clientCredentialType="UserName"/>
            </security>
        </binding>
      </wsHttpBinding>
    </bindings>

Когда я вызываю url для просмотра xamlx для службы, появляется следующая ошибка:

не удалось найти базу адрес, соответствующий схеме https для конечной точки с привязкой BasicHttpBinding. Зарегистрированные схемы базовых адресов являются [http]

Как я могу справиться с этой ошибкой ? Я вообще не использую https, но все равно получаю ошибку.

Я также попытался перейти на basichttpbinding вместо wshttp, но это дает аналогичную ошибку.

При смене securitymode на Message я получаю следующую ошибку: сервисный сертификат не предоставляется. Указать сертификат на обслуживание в ServiceCredentials

Есть ли способ использовать конфигурацию без сертификата?

2 2

2 ответа:

TransportWithMessageCredential означает, что вы хотите использовать безопасность транспорта и отправлять учетные данные в сообщении. Безопасность транспорта в данном случае означает HTTPS. Во-первых, realease WCF требовала, чтобы имя пользователя и пароль можно было использовать только при защищенной связи. Позже MS выпустила патч, который позволяет обходной путь, чтобы избежать HTTPS, но все еще не рекомендуется. В .NET 4.0 патч непосредственно включен.

Если вы хотите использовать учетные данные сообщения без защищенной связи, у вас есть чтобы создать пользовательскую привязку, аналогичную этой:

<bindings>
  <customBinding>
    <binding name="HttpWithAuthentication">
      <security authenticationMode="UserNameOverTransport" allowInsecureTranpsort="true" />
      <context /> <!-- needed for durable worklfows -->
      <textMessageEncoding messageVersion="Soap12Addressing10" />
      <httpTransport />
    </binding>
  </customBinding>
</bindings>

Проблема с allowInsecurTransport заключается в том, что это некоторое "быстрое исправление", которое не интегрируется со всеми функциями WCF. Так, например, когда вы используете его, ваш сервис не может генерировать WSDL / метаданные, потому что эта часть все еще требует безопасной связи.

Вы использовали TransportWithMessageCredential, Что означает обязательный HTTPS. Поэтому вам нужно либо изменить настройки безопасности, либо включить SSL.

WCF не допускает проверку подлинности открытым текстом по протоколу http, она требует https, и это поведение является преднамеренным - я бы на самом деле не согласился, но хорошо, что я не microsoft.

Если вам нужно включить аутентификацию открытым текстом, вам нужно вручную обработать сообщение в инспекторе сообщений.

Обновить

Вот моя реализация (это грубое и единственное доказательство концепции), но другой ответ лучше (встроенная поддержка в WCF 4.0):

  [Serializable()]
  public class ConsoleMessageTracer : BehaviorExtensionElement, 
  IClientMessageInspector ,IEndpointBehavior, System.Configuration.IConfigurationSectionHandler
  {

    private string _userName = string.Empty;
    private string _password = string.Empty;

    [XmlAttribute()]
    public string UserName
    {
      get { return _userName; }
      set { _userName = value; }
    }

    [XmlAttribute()]
    public string Password
    {
      get { return _password; }
      set { _password = value; }
    }


    private Message TraceMessage(MessageBuffer buffer)
    {
      Message msg = buffer.CreateMessage();
      Console.WriteLine("\n{0}\n", msg);
      return buffer.CreateMessage();
    }


    public void AfterReceiveReply(ref Message reply, object
        correlationState)
    {
      reply = TraceMessage(reply.CreateBufferedCopy(int.MaxValue));
    }

    public object BeforeSendRequest(ref Message request,
        IClientChannel channel)
    {

      request.Headers.Add(MessageHeader.CreateHeader("Security",
        "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd",
        tt, true, "http://www.isban.es/soap/actor/wssecurityUserPass")
        );

      return null;
    }

    public override Type BehaviorType
    {
      get { return this.GetType(); }
    }

    protected override object CreateBehavior()
    {
      return this;
    }

    #region IEndpointBehavior Members

    public void AddBindingParameters(ServiceEndpoint endpoint, BindingParameterCollection bindingParameters)
    {
      return;
    }

    public void ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime)
    {
      clientRuntime.MessageInspectors.Add(new ConsoleMessageTracer());
      //foreach (ClientOperation op in clientRuntime.Operations)
      //  op.ParameterInspectors.Add(new ConsoleMessageTracer());
    }

    public void ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher)
    {
      //endpointDispatcher.DispatchRuntime.MessageInspectors.Add(new ConsoleMessageTracer());
      //foreach (DispatchOperation op in endpointDispatcher.DispatchRuntime.Operations)
      //  op.ParameterInspectors.Add(new ConsoleMessageTracer());
    }

    public void Validate(ServiceEndpoint endpoint)
    {
      return;
    }

    #endregion

    #region IConfigurationSectionHandler Members

    public object Create(object parent, object configContext, XmlNode section)
    {
      return null;
    }

    #endregion
  }

    [DataContract(Namespace = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd")]
    //[DataContract(Namespace = "")]
    [Serializable()]
    public class UserNameTokenToken
    {
        [DataMember()]
        public UserNameToken UsernameToken;

        public UserNameTokenToken(UserNameToken token)
        {
            UsernameToken = token;
        }
    }

    [DataContract(Namespace = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd")]
    //[DataContract(Namespace = "")]
    [Serializable()]
    public class UserNameToken
    {
        [DataMember(Order = 1)]
        public string Username = string.Empty;
        [DataMember(Order = 2)]
        public string Password = string.Empty;

        public UserNameToken(string uname, string pass)
        {
            Username = uname;
            Password = pass;
        }

    }