Служба WCF показывает исключение при защите службы с помощью wshttpbinding и аутентификации по имени пользователя - PullRequest
2 голосов
/ 07 октября 2010

Я создал службу workflow в .net 4.0

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

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

<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, но выдает похожую ошибку.

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

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

Ответы [ 2 ]

3 голосов
/ 07 октября 2010

TransportWithMessageCredential означает, что вы хотите использовать безопасность транспорта и отправлять учетные данные в сообщении. Транспортная безопасность в данном случае означает HTTPS. Первый выпуск 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 / метаданные, потому что эта часть все еще требует защищенной связи.

3 голосов
/ 07 октября 2010

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

WCF не допускает аутентификацию открытого текста по протоколу http, для этого требуется https, и такое поведение является преднамеренным - на самом деле я не согласен, но я не Майкрософт.

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

UPDATE

Здесь была моя реализация (это грубая и единственная проверка концепции), но другой ответ лучше (встроенная поддержка в 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;
        }

    }
...