我有一个非常简单的 WCF Web 服务,客户在自己的 IIS 上托管该服务。
客户有自己的客户端,他们一直在测试环境中对其进行测试,一切都工作正常,直到他们禁用匿名身份验证并启用基本身份验证。一旦他们这样做了,他们就开始出现错误:
The authentication schemes configured on the host ('Basic') do not allow those configured on the binding 'BasicHttpBinding' ('Anonymous'). Please ensure that the SecurityMode is set to Transport or TransportCredentialOnly.
那么,我需要做什么才能使基本身份验证正常工作?
我的网络服务当前web.config
:
<configuration>
<system.web>
<compilation debug="true" targetFramework="4.5" />
<httpRuntime targetFramework="4.5" />
</system.web>
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior name="">
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="false" />
</behavior>
</serviceBehaviors>
</behaviors>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true"
multipleSiteBindingsEnabled="true" />
</system.serviceModel>
</configuration>
我有自己的测试客户端,可以针对我的网络服务运行。其目前的app.config
:
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
</startup>
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="BasicHttpBinding_IMyServiceSvc" />
</basicHttpBinding>
</bindings>
<client>
<endpoint address="http://localhost/MyServiceSvc.svc"
binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_IMyServiceSvc"
contract="MyServiceSvc.IMyServiceSvc"
name="BasicHttpBinding_IMyServiceSvc" />
</client>
</system.serviceModel>
</configuration>
当我在本地 IIS 上安装该服务并针对它运行客户端时,一切正常,并且启用了匿名身份验证。
我需要做什么才能在 IIS 中打开基本身份验证并将客户端和服务器配置为使用基本身份验证?
我当前的测试客户端代码:
public class BlackHillsCompletionSvcTest
{
static void Main(string[] args)
{
using (var client = new MyServiceSvcClient())
{
var data = new Data
{
id = "1",
description = "test data"
};
try
{
var result = client.receiveData(data);
}
catch (Exception ex)
{
var msg = ex.Message;
}
}
}
}
==尝试:==
根据 Pankaj Kapare 的建议,我将其添加到网络服务中web.config
:
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="httpBinding">
<security mode="TransportCredentialOnly">
<transport clientCredentialType="Basic" />
</security>
</binding>
</basicHttpBinding>
</bindings>
...
</system.serviceModel>
这样,我在创建客户端时遇到错误:
The binding at system.serviceModel/bindings/basicHttpBinding does not have a configured binding named 'BasicHttpBinding_IMyServiceSvc'. This is an invalid value for bindingConfiguration.
所以我将其添加到客户的app.config
:
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="BasicHttpBinding_IMyServiceSvc">
<security mode="TransportCredentialOnly">
<transport clientCredentialType="Basic" />
</security>
</binding>
</basicHttpBinding>
</bindings>
...
</system.serviceModel>
这样,我又得到了另一个错误:
The username is not provided. Specify username in ClientCredentials.
所以我在客户端添加了用户名和密码:
using (var client = new MyServiceSvcClient())
{
client.ClientCredentials.UserName.UserName = "myusername";
client.ClientCredentials.UserName.Password = "mypassword";
...
}
这样,我又收到另一个错误:
The requested service, 'http://localhost/MyServiceSvc.svc' could not be activated. Which got me wondering. So I loaded the .svc page in my browser, was asked to log in, and after I did, I saw this:
The authentication schemes configured on the host ('Basic') do not allow those configured on the binding 'BasicHttpBinding' ('Anonymous'). Please ensure that the SecurityMode is set to Transport or TransportCredentialOnly. Additionally, this may be resolved by changing the authentication schemes for this application through the IIS management tool, through the ServiceHost.Authentication.AuthenticationSchemes property, in the application configuration file at the <serviceAuthenticationManager> element, by updating the ClientCredentialType property on the binding, or by adjusting the AuthenticationScheme property on the HttpTransportBindingElement.
这就是客户所看到的。
Ideas?
== 也许有一个解决方案? ==
我认为可能缺少的是服务器上的服务定义,将绑定绑定到端点:
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="httpBinding">
<security mode="TransportCredentialOnly">
<transport clientCredentialType="Basic" />
</security>
</binding>
</basicHttpBinding>
</bindings>
<services>
<service
name="MyServiceSvcNs.MyServiceSvc"
behaviorConfiguration="ServiceWithMetaData"
>
<endpoint name="Default"
address=""
binding="basicHttpBinding"
bindingConfiguration="httpBinding"
contract="MyServiceSvcNs.IMyServiceSvc"
/>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="ServiceWithMetaData">
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="false" />
</behavior>
</serviceBehaviors>
</behaviors>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true"
multipleSiteBindingsEnabled="true" />
</system.serviceModel>
有了这个,事情似乎正在发挥作用。至少乍一看是这样。