#wcf #authentication
#wcf #аутентификация
Вопрос:
Я пытаюсь создать службу wcf, которая выполняет базовую аутентификацию, но у меня возникли некоторые проблемы.
Вот как выглядит мой web.config для службы:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.serviceModel>
<client />
<services>
<service name="Service.DataExchangeService" behaviorConfiguration="MyBehavior">
<endpoint address="" binding="wsHttpBinding" bindingConfiguration="wsDataImportEndpoint" contract="Service.IDataExchangeService">
<identity>
<dns value="localhost" />
</identity>
</endpoint>
<endpoint address="mex" binding="mexHttpsBinding" contract="IMetadataExchange" />
<host>
<baseAddresses>
<add baseAddress="http://localhost:8732/Design_Time_Addresses/DataExchange.Server.Service/Service1/" />
</baseAddresses>
</host>
</service>
</services>
<bindings>
<wsHttpBinding>
<binding name="wsDataImportEndpoint" maxBufferPoolSize="2147483647"
maxReceivedMessageSize="2147483647">
<readerQuotas maxDepth="32" maxStringContentLength="2147483647"
maxArrayLength="16384" maxBytesPerRead="4096" maxNameTableCharCount="16384" />
<security mode="Transport">
<transport clientCredentialType="Basic"/>
<message clientCredentialType="UserName" negotiateServiceCredential="true" />
</security>
</binding>
</wsHttpBinding>
</bindings>
<behaviors>
<serviceBehaviors>
<behavior name="MyBehavior">
<serviceMetadata httpsGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="true" />
<serviceCredentials>
<userNameAuthentication customUserNamePasswordValidatorType="DataExchange.Server.Service.UserNameValidator, DataExchange.Server.Service"
userNamePasswordValidationMode="Custom" />
</serviceCredentials>
</behavior>
<behavior name="">
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="false" />
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
<connectionStrings>
<add name="ApplicationServices" connectionString="data source=sharept07mssqlserver2008;initial catalog=VOS.Membership;integrated security=True;" providerName="System.Data.SqlClient" />
<add name="ROSEntities" connectionString="metadata=res://*/ROSModel.csdl|res://*/ROSModel.ssdl|res://*/ROSModel.msl;provider=System.Data.SqlClient;provider connection string=amp;quot;data source=sharept07MSSQLServer2008;initial catalog=VOS;integrated security=True;multipleactiveresultsets=True;App=EntityFrameworkamp;quot;" providerName="System.Data.EntityClient" />
</connectionStrings>
</configuration>
и вот как выглядит мой файл конфигурации клиента:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.serviceModel>
<bindings>
<wsHttpBinding>
<binding name="WSHttpBinding_IDataExchangeService" closeTimeout="00:01:00"
openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"
bypassProxyOnLocal="false" transactionFlow="false" hostNameComparisonMode="StrongWildcard"
maxBufferPoolSize="524288" maxReceivedMessageSize="2147483647"
messageEncoding="Text" textEncoding="utf-8" useDefaultWebProxy="true"
allowCookies="false">
<readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
maxBytesPerRead="4096" maxNameTableCharCount="16384" />
<reliableSession ordered="true" inactivityTimeout="00:10:00"
enabled="false" />
<security mode="Transport">
<transport clientCredentialType="Basic" proxyCredentialType="None"
realm="" />
<message clientCredentialType="UserName" negotiateServiceCredential="true" />
</security>
</binding>
</wsHttpBinding>
</bindings>
<client>
<endpoint address="https://server.com:446/DataExchangeService/DataExchangeService.svc"
binding="wsHttpBinding" bindingConfiguration="WSHttpBinding_IDataExchangeService"
contract="DataExchangeSvc.IDataExchangeService" name="WSHttpBinding_IDataExchangeService">
<identity>
<dns value="localhost" />
</identity>
</endpoint>
</client>
</system.serviceModel>
</configuration>
и вот как я вызываю службу внутри своего клиента:
static void Main(string[] args)
{
using (var client = new DataExchangeSvc.DataExchangeServiceClient())
{
client.ClientCredentials.UserName.UserName = "test";
client.ClientCredentials.UserName.Password = "test";
var data = client.RetrieveData();
}
}
Когда я устанавливаю для транспортного режима значение «Нет» в узле безопасности в файле конфигурации службы, вышеуказанное работает отлично, если я опускаю строки учетных данных, но в тот момент, когда я меняю его на Basic, я продолжаю получать эту ошибку:
There was no endpoint listening at https://server.com:446/DataExchangeService/DataExchangeService.svc that could accept the message. This is often caused by an incorrect address or SOAP action. See InnerException, if present, for more details.
Я действительно не знаю, что происходит, поэтому, если кто-нибудь может каким-либо образом помочь мне, это было бы чрезвычайно полезно.
Спасибо
Ответ №1:
Я думаю, что вы действительно хотите здесь использовать TransportWithMessageCredential
вместо just Transport
. Простое использование <security mode="Transport">
приведет к тому, что ваша служба будет работать по протоколу HTTPS, но не имеет ничего общего с использованием учетных данных для аутентификации. Если вы используете <security mode="TransportWithMessageCredential">
, вы можете использовать HTTPS и иметь имя пользователя и пароль. Вот статья MSDN об этом.
Редактировать
Если вы действительно просто хотите использовать Transport
, удалите <message>
узел из конфигурации вашей службы.