Jef*_*ege 4 iis wcf web-services basic-authentication
我有一个非常简单的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.
Run Code Online (Sandbox Code Playgroud)
那么,我需要做些什么来使基本身份验证工作?
我的网络服务目前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>
Run Code Online (Sandbox Code Playgroud)
我有自己的测试客户端,我可以针对我的webservice运行.目前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>
Run Code Online (Sandbox Code Playgroud)
当我在本地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;
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
==尝试:==
根据Pankaj Kapare的建议,我将其添加到网络服务中web.config:
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="httpBinding">
<security mode="TransportCredentialOnly">
<transport clientCredentialType="Basic" />
</security>
</binding>
</basicHttpBinding>
</bindings>
...
</system.serviceModel>
Run Code Online (Sandbox Code Playgroud)
有了这个,我在创建客户端时遇到错误:
The binding at system.serviceModel/bindings/basicHttpBinding does not have a configured binding named 'BasicHttpBinding_IMyServiceSvc'. This is an invalid value for bindingConfiguration.
Run Code Online (Sandbox Code Playgroud)
所以我把它添加到客户端app.config:
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="BasicHttpBinding_IMyServiceSvc">
<security mode="TransportCredentialOnly">
<transport clientCredentialType="Basic" />
</security>
</binding>
</basicHttpBinding>
</bindings>
...
</system.serviceModel>
Run Code Online (Sandbox Code Playgroud)
有了这个,我又得到了一个错误:
The username is not provided. Specify username in ClientCredentials.
Run Code Online (Sandbox Code Playgroud)
所以我在我的客户端添加了用户名和密码:
using (var client = new MyServiceSvcClient())
{
client.ClientCredentials.UserName.UserName = "myusername";
client.ClientCredentials.UserName.Password = "mypassword";
...
}
Run Code Online (Sandbox Code Playgroud)
有了这个,我又得到了一个错误:
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.
Run Code Online (Sandbox Code Playgroud)
这是客户所看到的.
想法?
==也许是一个解决方案?==
我认为可能缺少的是服务器上的服务定义,将绑定绑定到端点:
<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>
Run Code Online (Sandbox Code Playgroud)
有了这个,事情似乎有效.至少乍一看.
好的,我明白了.
首先,在IIS管理器中,您需要关闭匿名身份验证,并启用基本身份验证.这可能需要先启用基本身份验证,然后重新启动IIS管理器.这是基本的IIS内容,而不是我的问题的一部分.
然后,我们需要更改Web服务的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>
Run Code Online (Sandbox Code Playgroud)
我们需要将其更改为:
<configuration>
<system.web>
<compilation debug="true" targetFramework="4.5" />
<httpRuntime targetFramework="4.5" />
</system.web>
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="httpTransportCredentialOnlyBinding">
<security mode="TransportCredentialOnly">
<transport clientCredentialType="Basic" />
</security>
</binding>
</basicHttpBinding>
</bindings>
<services>
<service
name="MyServiceSvcNs.MyServiceSvc"
behaviorConfiguration="ServiceWithMetaData"
>
<endpoint name="Default"
address=""
binding="basicHttpBinding"
bindingConfiguration="httpTransportCredentialOnlyBinding"
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>
</configuration>
Run Code Online (Sandbox Code Playgroud)
我们正在做的是使用TransportCredentialOnly安全性定义basicHttpBinding.然后我们定义一个服务,其端点使用该绑定.
然后在客户端,我们有:
<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>
Run Code Online (Sandbox Code Playgroud)
这需要改为:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
</startup>
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="httpTransportCredentialOnlyBinding">
<security mode="TransportCredentialOnly">
<transport clientCredentialType="Basic" />
</security>
</binding>
</basicHttpBinding>
</bindings>
<client>
<endpoint
address="http://localhost/MyServiceSvc.svc"
binding="basicHttpBinding"
bindingConfiguration="httpTransportCredentialOnlyBinding"
contract="MyServiceSvc.IMyServiceSvc"
name="BasicHttpBinding_IMyServiceSvc"
/>
</client>
</system.serviceModel>
</configuration>
Run Code Online (Sandbox Code Playgroud)
在这里,我们再次使用TransportCredentialOnly安全性创建basicHttpBinding,我们正在修改端点以使用它.