Как пройти аутентификацию в сервисах WCF в BasicHttpBinding?
Я разрабатываю сервисы WCF с basicHttpBinding, эти сервисы должны быть доступны с использованием.net 1.1 и.net 2.0, для этой цели я использую basicHttpBinding.
В старых веб-сервисах ASMX я использовал один заголовок Soap (AuthHeader) для аутентификации пользователя при каждом запросе.
Как я могу пройти аутентификацию в WCF, используя basicHttpBinding? Любой образец или учебник будет полезным.
NRK
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();
}
Прежде всего - да, вы можете! Это зависит от того, используете ли вы транспорт или привязку сообщений - если вы выходите в Интернет, вы с большей вероятностью будете использовать безопасность на основе сообщений.
К сожалению, для безопасности на основе сообщений 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 - отличный ресурс.
Проверьте сценарии здесь, чтобы попытаться сопоставить один с вашей ситуацией. Каждый сценарий снабжен списком элементов, необходимых для реализации решения.