具有 BasicAuthentication 问题的 WCF
WCF with BasicAuthentification problems
我几乎没有尝试为我的 WCF(在 IIS 8.5 上发布)设置 BasicAuthentification。但我总是得到这些错误之一:
http request was forbidden with client authentication scheme 'basic'. Got following authentificationheader "Digest qop="auth",algorithm=MD5-sess,nonce="someMD5stuff",charset=utf-8,realm="Digest",Negotiate,NTLM,Basic realm="localhost"" from the server.
或
The HTTP request was forbidden with client authentication scheme 'Basic'. Got authentificationheader "Basic realm="localhost"" from server.
我的 web.config 服务器端(在 WCF 中):
<system.serviceModel>
<services>
<service name="WCF_for_APP.Service1">
<endpoint
address=""
binding="basicHttpBinding"
contract="WCF_for_APP.Service"/>
</service>
</services>
<bindings>
<basicHttpBinding>
<binding name="BasicHttpBinding_IPersonService" />
<binding>
<security mode="TransportCredentialOnly">
<transport clientCredentialType="Basic" proxyCredentialType="None" realm=""/>
</security>
</binding>
</basicHttpBinding>
</bindings>
<client>
<endpoint address="http://somewhere/customerService"
binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_IPersonService"
contract="PersonService.IPersonService" name="BasicHttpBinding_IPersonStateService" />
</client>
<behaviors>
<serviceBehaviors>
<behavior>
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="false"/>
<serviceAuthenticationManager authenticationSchemes="Basic"></serviceAuthenticationManager>
<serviceCredentials>
<userNameAuthentication userNamePasswordValidationMode="Custom"
customUserNamePasswordValidatorType="CustomerValidator.SecureBindingUsernamePasswordValidator, CustomerValidator" />
</serviceCredentials>
</behavior>
</serviceBehaviors>
</behaviors>
</system.servicemodel>
我试过为 bindingConfiguration 等设置名称,但它没有改变任何东西。
我尝试在 ASP 应用程序中通过 Channelfactory 客户端访问我的 WCF:
EndpointAddress endpointAddress = new EndpointAddress(endpointadress);
BasicHttpBinding basicHttpBinding = new BasicHttpBinding();
basicHttpBinding.ReaderQuotas.MaxBytesPerRead = Int16.MaxValue;
basicHttpBinding.MaxReceivedMessageSize = int.MaxValue;
basicHttpBinding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Basic;
basicHttpBinding.Security.Mode = BasicHttpSecurityMode.TransportCredentialOnly;
ChannelFactory<Service> channelFactory = null;
Service client = null;
channelFactory = new ChannelFactory<Service>(basicHttpBinding, endpointAddress);
channelFactory.Credentials.UserName.UserName = ConfigurationManager.AppSettings["wcfUser"].ToString();
channelFactory.Credentials.UserName.Password = ConfigurationManager.AppSettings["wcfPW"].ToString();
try
{
client = channelFactory.CreateChannel();
string a = client.SendMail();
}
catch(Exception e)
{
Response.Write(e.Message);
}
IIS 上的基本身份验证已激活。我真的不想切换到 HTTPS 和证书,因为我只需要这个 basicauthent 来保证内部安全。我什至无法使用 visual studio wcf testclient 启动 WCF,但没有身份验证设置一切正常。
WCF 和 ASP 都发布在我的本地 IIS 上。
有什么问题的建议吗?我是否必须使用相同的凭据将用户添加到我的本地系统?
** 编辑 **
我想我知道这个问题了!在我的 WCF 中,我调用了另一个 WCF(来自客户),这个与我的安全设置相结合正在制造麻烦。那我该如何解决呢?我的带有服务器端配置的 WCF 和带有客户端配置的客户 WCF 合二为一 web.config? (客户 WCF 也通过 ChannelFactory 调用)因为如果我命名 bindingconfigs 它不会改变任何东西(参见上面的代码)。
通过 ChannelFactory 调用客户 WCF 的代码类似于上面的代码。
这可能是问题所在吗? 2 WCF - 一个服务器端,一个用于调用?!
我创建了测试项目,它正在运行。代码如下:
IService1 接口:
namespace WcfTestService
{
// NOTE: You can use the "Rename" command on the "Refactor" menu to change the interface name "IService1" in both code and config file together.
[ServiceContract]
public interface IService1
{
[OperationContract]
string GetData(int value);
[OperationContract]
CompositeType GetDataUsingDataContract(CompositeType composite);
// TODO: Add your service operations here
}
// Use a data contract as illustrated in the sample below to add composite types to service operations.
[DataContract]
public class CompositeType
{
bool boolValue = true;
string stringValue = "Hello ";
[DataMember]
public bool BoolValue
{
get { return boolValue; }
set { boolValue = value; }
}
[DataMember]
public string StringValue
{
get { return stringValue; }
set { stringValue = value; }
}
}
}
服务 1 class:
namespace WcfTestService
{
// NOTE: You can use the "Rename" command on the "Refactor" menu to change the class name "Service1" in code, svc and config file together.
// NOTE: In order to launch WCF Test Client for testing this service, please select Service1.svc or Service1.svc.cs at the Solution Explorer and start debugging.
public class Service1 : IService1
{
public string GetData(int value)
{
return string.Format("You entered: {0}", value);
}
public CompositeType GetDataUsingDataContract(CompositeType composite)
{
if (composite == null)
{
throw new ArgumentNullException("composite");
}
if (composite.BoolValue)
{
composite.StringValue += "Suffix";
}
return composite;
}
}
}
web.config 文件:
<?xml version="1.0"?>
<configuration>
<system.web>
<compilation debug="true" targetFramework="4.0" />
</system.web>
<system.serviceModel>
<services>
<service name="WcfTestService.Service1" behaviorConfiguration="HttpBehavior">
<endpoint address="" binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding" contract="WcfTestService.IService1" />
</service>
</services>
<bindings>
<basicHttpBinding>
<binding name="BasicHttpBinding" >
<readerQuotas />
<security mode="TransportCredentialOnly">
<transport clientCredentialType="Basic" realm="" />
</security>
</binding>
</basicHttpBinding>
</bindings>
<behaviors>
<serviceBehaviors>
<behavior name="HttpBehavior">
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="false" />
</behavior>
</serviceBehaviors>
</behaviors>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
</system.serviceModel>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true"/>
<!--
To browse web app root directory during debugging, set the value below to true.
Set to false before deployment to avoid disclosing web app folder information.
-->
<directoryBrowse enabled="true"/>
</system.webServer>
</configuration>
在 IIS 上启用基本身份验证,禁用匿名。
WCF 客户端控制台应用程序:
namespace WcfTestClient
{
class Program
{
static void Main(string[] args)
{
EndpointAddress endpointAddress = new EndpointAddress(@"http://localhost/Service1.svc");
BasicHttpBinding basicHttpBinding = new BasicHttpBinding();
basicHttpBinding.MaxReceivedMessageSize = int.MaxValue;
basicHttpBinding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Basic;
basicHttpBinding.Security.Mode = BasicHttpSecurityMode.TransportCredentialOnly;
var channelFactory = new ChannelFactory<WcfTestService.IService1>(basicHttpBinding, endpointAddress);
channelFactory.Credentials.UserName.UserName = @"server\someuser";
channelFactory.Credentials.UserName.Password = @"somepass";
try
{
var client = channelFactory.CreateChannel();
string a = client.GetData(55);
Console.Write(e.Message);
}
catch (Exception e)
{
Console.Write(e.Message);
}
}
}
}
我的 BasicAuthentification 一切正常。
错误是我通过我的 WCF 调用的另一个 WCF,由于我的 WCF 中的安全设置,我无法调试(不是挂起处理或测试客户端)并且因为错误中没有详细信息消息我没有找到这个错误的来源。另一个 WCF 抛出错误 "Basic" isn't allowed 所以我的客户在他的 IIS 上做了一些更改(可能)。
而且我必须添加一个本地用户,其凭据与我在 WCF 中使用的凭据相同。不知道,但是是的 - 一切都很好,我必须等待我的客户告诉我他们的设置。
我几乎没有尝试为我的 WCF(在 IIS 8.5 上发布)设置 BasicAuthentification。但我总是得到这些错误之一:
http request was forbidden with client authentication scheme 'basic'. Got following authentificationheader "Digest qop="auth",algorithm=MD5-sess,nonce="someMD5stuff",charset=utf-8,realm="Digest",Negotiate,NTLM,Basic realm="localhost"" from the server.
或
The HTTP request was forbidden with client authentication scheme 'Basic'. Got authentificationheader "Basic realm="localhost"" from server.
我的 web.config 服务器端(在 WCF 中):
<system.serviceModel>
<services>
<service name="WCF_for_APP.Service1">
<endpoint
address=""
binding="basicHttpBinding"
contract="WCF_for_APP.Service"/>
</service>
</services>
<bindings>
<basicHttpBinding>
<binding name="BasicHttpBinding_IPersonService" />
<binding>
<security mode="TransportCredentialOnly">
<transport clientCredentialType="Basic" proxyCredentialType="None" realm=""/>
</security>
</binding>
</basicHttpBinding>
</bindings>
<client>
<endpoint address="http://somewhere/customerService"
binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_IPersonService"
contract="PersonService.IPersonService" name="BasicHttpBinding_IPersonStateService" />
</client>
<behaviors>
<serviceBehaviors>
<behavior>
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="false"/>
<serviceAuthenticationManager authenticationSchemes="Basic"></serviceAuthenticationManager>
<serviceCredentials>
<userNameAuthentication userNamePasswordValidationMode="Custom"
customUserNamePasswordValidatorType="CustomerValidator.SecureBindingUsernamePasswordValidator, CustomerValidator" />
</serviceCredentials>
</behavior>
</serviceBehaviors>
</behaviors>
</system.servicemodel>
我试过为 bindingConfiguration 等设置名称,但它没有改变任何东西。
我尝试在 ASP 应用程序中通过 Channelfactory 客户端访问我的 WCF:
EndpointAddress endpointAddress = new EndpointAddress(endpointadress);
BasicHttpBinding basicHttpBinding = new BasicHttpBinding();
basicHttpBinding.ReaderQuotas.MaxBytesPerRead = Int16.MaxValue;
basicHttpBinding.MaxReceivedMessageSize = int.MaxValue;
basicHttpBinding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Basic;
basicHttpBinding.Security.Mode = BasicHttpSecurityMode.TransportCredentialOnly;
ChannelFactory<Service> channelFactory = null;
Service client = null;
channelFactory = new ChannelFactory<Service>(basicHttpBinding, endpointAddress);
channelFactory.Credentials.UserName.UserName = ConfigurationManager.AppSettings["wcfUser"].ToString();
channelFactory.Credentials.UserName.Password = ConfigurationManager.AppSettings["wcfPW"].ToString();
try
{
client = channelFactory.CreateChannel();
string a = client.SendMail();
}
catch(Exception e)
{
Response.Write(e.Message);
}
IIS 上的基本身份验证已激活。我真的不想切换到 HTTPS 和证书,因为我只需要这个 basicauthent 来保证内部安全。我什至无法使用 visual studio wcf testclient 启动 WCF,但没有身份验证设置一切正常。 WCF 和 ASP 都发布在我的本地 IIS 上。
有什么问题的建议吗?我是否必须使用相同的凭据将用户添加到我的本地系统?
** 编辑 **
我想我知道这个问题了!在我的 WCF 中,我调用了另一个 WCF(来自客户),这个与我的安全设置相结合正在制造麻烦。那我该如何解决呢?我的带有服务器端配置的 WCF 和带有客户端配置的客户 WCF 合二为一 web.config? (客户 WCF 也通过 ChannelFactory 调用)因为如果我命名 bindingconfigs 它不会改变任何东西(参见上面的代码)。
通过 ChannelFactory 调用客户 WCF 的代码类似于上面的代码。 这可能是问题所在吗? 2 WCF - 一个服务器端,一个用于调用?!
我创建了测试项目,它正在运行。代码如下:
IService1 接口:
namespace WcfTestService
{
// NOTE: You can use the "Rename" command on the "Refactor" menu to change the interface name "IService1" in both code and config file together.
[ServiceContract]
public interface IService1
{
[OperationContract]
string GetData(int value);
[OperationContract]
CompositeType GetDataUsingDataContract(CompositeType composite);
// TODO: Add your service operations here
}
// Use a data contract as illustrated in the sample below to add composite types to service operations.
[DataContract]
public class CompositeType
{
bool boolValue = true;
string stringValue = "Hello ";
[DataMember]
public bool BoolValue
{
get { return boolValue; }
set { boolValue = value; }
}
[DataMember]
public string StringValue
{
get { return stringValue; }
set { stringValue = value; }
}
}
}
服务 1 class:
namespace WcfTestService
{
// NOTE: You can use the "Rename" command on the "Refactor" menu to change the class name "Service1" in code, svc and config file together.
// NOTE: In order to launch WCF Test Client for testing this service, please select Service1.svc or Service1.svc.cs at the Solution Explorer and start debugging.
public class Service1 : IService1
{
public string GetData(int value)
{
return string.Format("You entered: {0}", value);
}
public CompositeType GetDataUsingDataContract(CompositeType composite)
{
if (composite == null)
{
throw new ArgumentNullException("composite");
}
if (composite.BoolValue)
{
composite.StringValue += "Suffix";
}
return composite;
}
}
}
web.config 文件:
<?xml version="1.0"?>
<configuration>
<system.web>
<compilation debug="true" targetFramework="4.0" />
</system.web>
<system.serviceModel>
<services>
<service name="WcfTestService.Service1" behaviorConfiguration="HttpBehavior">
<endpoint address="" binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding" contract="WcfTestService.IService1" />
</service>
</services>
<bindings>
<basicHttpBinding>
<binding name="BasicHttpBinding" >
<readerQuotas />
<security mode="TransportCredentialOnly">
<transport clientCredentialType="Basic" realm="" />
</security>
</binding>
</basicHttpBinding>
</bindings>
<behaviors>
<serviceBehaviors>
<behavior name="HttpBehavior">
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="false" />
</behavior>
</serviceBehaviors>
</behaviors>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
</system.serviceModel>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true"/>
<!--
To browse web app root directory during debugging, set the value below to true.
Set to false before deployment to avoid disclosing web app folder information.
-->
<directoryBrowse enabled="true"/>
</system.webServer>
</configuration>
在 IIS 上启用基本身份验证,禁用匿名。
WCF 客户端控制台应用程序:
namespace WcfTestClient
{
class Program
{
static void Main(string[] args)
{
EndpointAddress endpointAddress = new EndpointAddress(@"http://localhost/Service1.svc");
BasicHttpBinding basicHttpBinding = new BasicHttpBinding();
basicHttpBinding.MaxReceivedMessageSize = int.MaxValue;
basicHttpBinding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Basic;
basicHttpBinding.Security.Mode = BasicHttpSecurityMode.TransportCredentialOnly;
var channelFactory = new ChannelFactory<WcfTestService.IService1>(basicHttpBinding, endpointAddress);
channelFactory.Credentials.UserName.UserName = @"server\someuser";
channelFactory.Credentials.UserName.Password = @"somepass";
try
{
var client = channelFactory.CreateChannel();
string a = client.GetData(55);
Console.Write(e.Message);
}
catch (Exception e)
{
Console.Write(e.Message);
}
}
}
}
我的 BasicAuthentification 一切正常。
错误是我通过我的 WCF 调用的另一个 WCF,由于我的 WCF 中的安全设置,我无法调试(不是挂起处理或测试客户端)并且因为错误中没有详细信息消息我没有找到这个错误的来源。另一个 WCF 抛出错误 "Basic" isn't allowed 所以我的客户在他的 IIS 上做了一些更改(可能)。
而且我必须添加一个本地用户,其凭据与我在 WCF 中使用的凭据相同。不知道,但是是的 - 一切都很好,我必须等待我的客户告诉我他们的设置。