Как пройти аутентификацию в службах WCF в BasicHttpBinding?

Я разрабатываю службы WCF с помощью basicHttpBinding, эти службы должны быть доступны с использованием .net 1.1 и .net 2.0, для этой цели я использую basicHttpBinding.
В старых веб-службах ASMX я оценивал один заголовок мыла (AuthHeader) для аутентификации пользователя при каждом запросе.

Как я могу аутентифицироваться в WCF с помощью basicHttpBinding ? Любой образец или учебник будет полезным.


nRk


person nRk    schedule 24.11.2009    source источник


Ответы (3)


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

В этом случае вы должны реализовать свои собственные IDispatchMessageInspector и IClientMessageInspector, например

[AttributeUsage(AttributeTargets.Class)]
public class CredentialsExtractorBehaviorAttribute : Attribute, IContractBehavior, IDispatchMessageInspector
{
    #region IContractBehavior implementation.

    public void ApplyDispatchBehavior(ContractDescription contractDescription, ServiceEndpoint endpoint,
                                      DispatchRuntime dispatchRuntime)
    {
        dispatchRuntime.MessageInspectors.Add(this);
    }

    ... empty interface methods impl skipped ...

    #endregion

    #region IDispatchMessageInspector implementation.

    public object AfterReceiveRequest(ref Message request, IClientChannel channel, InstanceContext instanceContext)
    {
        int i = request.Headers.FindHeader("username", "sec");
        if (-1 != i)
        {
            string username = request.Headers.GetHeader<string>("username", "sec");
            ... do smth ...
        }
        return null;
    }

    public void BeforeSendReply(ref Message reply, object correlationState)
    {
        return;
    }

    #endregion
}

В примере я поместил в заголовок только имя пользователя, но вы можете реализовать свой класс, содержащий имя пользователя и пароль, и использовать его вместо строки. На клиенте:

internal class CredentialsInserter : IContractBehavior, IClientMessageInspector
{
    private string m_username;

    public CredentialsInserter(string username)
    {
        m_username = username;
    }

    #region IContractBehavior implementation.

    ... empty interface methods impl skipped ...

    public void ApplyClientBehavior(ContractDescription contractDescription, ServiceEndpoint endpoint,
                                    ClientRuntime clientRuntime)
    {
        clientRuntime.MessageInspectors.Add(this);
    }

    #endregion

    #region IClientMessageInspector implementation.

    public object BeforeSendRequest(ref Message request, IClientChannel channel)
    {
        MessageHeader<string> mh = new MessageHeader<string>(m_username);
        request.Headers.Add(mh.GetUntypedHeader("username", "sec"));
        return null;
    }

    public void AfterReceiveReply(ref Message reply, object correlationState)
    {
        return;
    }

    #endregion
}

Затем вы должны поместить атрибут CredentialsExtractorBehaviorAttribute в свой класс реализации службы.

[CredentialsExtractorBehavior]
public class DummyService : IDummyService
{
   ... impl ...
}

А на стороне клиента нужно сделать следующее:

        using (DummyServiceClient c = new DummyServiceClient("TcpEndpoint"))
        {
            c.ChannelFactory.Endpoint.Contract.Behaviors.Add(
                new CredentialsInserter("_username_"));
            c.DummyMethod();
        }
person fspirit    schedule 18.12.2009

Прежде всего - да, можно! Это зависит от того, используете ли вы транспортную привязку или привязку сообщений - если вы выходите в Интернет, вы с большей вероятностью будете использовать безопасность на основе сообщений.

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

wsHttpBinding, с другой стороны, также поддерживает имя пользователя / пароль или другие методы.

Вы должны настроить wsHttpBinding с учетными данными клиента с именем пользователя и паролем поверх безопасности на основе сообщений следующим образом:

  <system.serviceModel>
    <bindings>
      <wsHttpBinding>
        <binding name="wsUserName">
          <security mode="Message">
            <message clientCredentialType="UserName"/>
          </security>
        </binding>
      </wsHttpBinding>
    </bindings>
    <services>
      <service name="yourservice">
        <endpoint name="YourEndpoint"
                  address=""
                  binding="wsHttpBinding"
                  bindingConfiguration="wsUserName"
                  contract="IYourService" />
      </service>
    </services>
  </system.serviceModel>

Раздел под <bindings> определяет конфигурацию привязки для wsHttpBinding, которая использует защиту сообщений с учетными данными клиента с именем пользователя и паролем.

Раздел под <service> определяет образец службы, которая использует wsHttpBinding и ссылается на ту конфигурацию привязки, которую мы только что определили.

На стороне сервера теперь вы можете использовать имя пользователя и пароль, которые отправляются по сети, для проверки ваших вызывающих абонентов либо в вашей Active Directory (каждому вызывающему требуется учетная запись AD с вами), либо в базе данных системы членства ASP.NET; или, если вам действительно нужно, вы также можете написать свой собственный механизм аутентификации.

Найдите много полезной информации о безопасности WCF на Codeplex - отличный ресурс .

person marc_s    schedule 24.11.2009
comment
Спасибо, marc_s, я просмотрю материал codeplex. Итак, я могу проверять только сертификаты в basicHttpBiding. это означает, что я не могу проверить пользователя по имени пользователя и паролю? Есть ли какие-либо другие в basichttpBiding для проверки / аутентификации по имени пользователя и паролю? - nrk - person nRk; 24.11.2009
comment
@nrk: да, если вы используете безопасность сообщений в basicHttpBinding, вы можете использовать только сертификаты для аутентификации. Если вы будете использовать транспортную безопасность, вы можете использовать другие средства аутентификации. - person marc_s; 24.11.2009

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

person Tanner    schedule 03.12.2009