[英]basicHttpBinding authentication error
I am new on web services and I need to implement basicHttpBinding
to an existing web service with wsHttpsBinding
and basicHttpBinding
for a C# desktop application. 我是Web服务的新手,我需要使用
wsHttpsBinding
和basicHttpBinding
为C#桌面应用程序对现有的Web服务实现basicHttpBinding
。 When I try to consume the service with the desktop application I get the following error: 当我尝试通过桌面应用程序使用该服务时,出现以下错误:
The HTTP request was forbidden with client authentication scheme 'Anonymous'.
客户端身份验证方案“匿名”禁止HTTP请求。
The web.config file on the web service with the basicHttpBinding
and the wsHttpsBinding
looks like this: 具有
basicHttpBinding
和wsHttpsBinding
的Web服务上的web.config文件如下所示:
<system.serviceModel>
<diagnostics>
<messageLogging logEntireMessage="true" logMalformedMessages="true"
logMessagesAtServiceLevel="true" logMessagesAtTransportLevel="true"
maxMessagesToLog="25000">
<filters>
<clear />
</filters>
</messageLogging>
</diagnostics>
<behaviors>
<serviceBehaviors>
<behavior name="SecureBehave">
<serviceCredentials>
<clientCertificate>
<authentication certificateValidationMode="PeerTrust"/>
</clientCertificate>
<userNameAuthentication userNamePasswordValidationMode="Custom" customUserNamePasswordValidatorType="HIBridgeLib.HIBridgeService.Security.MessageSecurityValidator, HIBridgeLib"/>
<!--
<serviceCertificate findValue="WCfServer"
storeLocation="CurrentUser"
storeName="My"
x509FindType="FindBySubjectName" />
-->
</serviceCredentials>
<serviceMetadata httpGetEnabled="True" httpsGetEnabled="True"/>
<serviceDebug includeExceptionDetailInFaults="True" />
</behavior>
</serviceBehaviors>
</behaviors>
<bindings>
<wsHttpBinding>
<binding name="HIBridge_SSLBinding" maxBufferPoolSize="2147483647" maxReceivedMessageSize="2147483647">
<security mode="TransportWithMessageCredential">
<transport clientCredentialType="Certificate" proxyCredentialType="None" realm="" />
<message clientCredentialType="UserName" negotiateServiceCredential="True" establishSecurityContext="True" />
</security>
</binding>
</wsHttpBinding>
<basicHttpBinding>
<binding name="HIBridge_BasicBinding" maxBufferPoolSize="2147483647" maxReceivedMessageSize="2147483647">
<security mode="Transport">
<transport clientCredentialType="Certificate" proxyCredentialType="None" realm="" />
</security>
<readerQuotas maxStringContentLength="2147483647" />
</binding>
</basicHttpBinding>
</bindings>
<services>
<service name="HIBridgeWebService.HIBridgeService" behaviorConfiguration="SecureBehave">
<endpoint address="basic" binding="basicHttpBinding" bindingConfiguration="HIBridge_BasicBinding" contract="HIBridgeLib.HIBridgeService.IHIBridgeService"></endpoint>
<endpoint address="ws" binding="wsHttpBinding" bindingConfiguration="HIBridge_SSLBinding" contract="HIBridgeLib.HIBridgeService.IHIBridgeService"></endpoint>
<host>
<baseAddresses>
<add baseAddress="https://10.50.1.85:1125/HIBridge/HIBridgeService.svc" />
</baseAddresses>
</host>
</service>
</services>
The userNameAuthentication looks like this: userNameAuthentication看起来像这样:
namespace HIBridgeLib.HIBridgeService.Security
{
public class MessageSecurityValidator : UserNamePasswordValidator
{
private const string USERNAME = "username";
private const string PASSWORD = "password";
public override void Validate(string userName, string password)
{
if (userName == null || password == null)
{
throw new ArgumentNullException();
}
if (USERNAME.Equals(userName) && PASSWORD.Equals(password))
{
}
else
{
throw new FaultException("Invalid Message Security Credentials");
}
}
}
}
And my desktop application code looks like this to consume the web service: 我的桌面应用程序代码看起来像这样来使用Web服务:
ChannelFactory<HIBridgeLib.HIBridgeService.IHIBridgeService> myChannelFactory = null;
HIBridgeLib.HIBridgeService.IHIBridgeService HIBridgeService = null;
System.ServiceModel.BasicHttpBinding basicHTTPBinding = new System.ServiceModel.BasicHttpBinding();
basicHTTPBinding.Name = "HIBridge_BasicBinding";
basicHTTPBinding.OpenTimeout = TimeSpan.FromMinutes(1);
basicHTTPBinding.CloseTimeout = TimeSpan.FromMinutes(1);
basicHTTPBinding.SendTimeout = TimeSpan.FromMinutes(1);
basicHTTPBinding.ReceiveTimeout = TimeSpan.FromMinutes(10);
basicHTTPBinding.BypassProxyOnLocal = false;
basicHTTPBinding.HostNameComparisonMode = System.ServiceModel.HostNameComparisonMode.StrongWildcard;
basicHTTPBinding.MaxBufferPoolSize = 2147483647;
basicHTTPBinding.MaxReceivedMessageSize = 2147483647;
basicHTTPBinding.MessageEncoding = System.ServiceModel.WSMessageEncoding.Text;
basicHTTPBinding.TextEncoding = Encoding.UTF8;
basicHTTPBinding.UseDefaultWebProxy = true;
basicHTTPBinding.AllowCookies = false;
basicHTTPBinding.Security.Mode = System.ServiceModel.BasicHttpSecurityMode.TransportWithMessageCredential;
basicHTTPBinding.Security.Transport.ClientCredentialType = System.ServiceModel.HttpClientCredentialType.Certificate;
basicHTTPBinding.Security.Transport.ProxyCredentialType = System.ServiceModel.HttpProxyCredentialType.None;
basicHTTPBinding.Security.Transport.Realm = "";
System.ServiceModel.EndpointAddress endpointAddress = null;
if (LocalMedCart.CartProfile.ConsoleHostname.Contains("/HIBridge/HIBridgeService.svc"))
endpointAddress = new System.ServiceModel.EndpointAddress(LocalMedCart.CartProfile.ConsoleHostname + "/basic");
else
endpointAddress = new System.ServiceModel.EndpointAddress(string.Format("https://{0}:{1}/HIBridge/HIBridgeService.svc/basic", LocalMedCart.CartProfile.ConsoleHostname, LocalMedCart.CartProfile.CommunicationPort));
HIBridgeLib.HIBridgeService.Security.PermissiveCertificatePolicy.Enact(string.Format("CN={0}", LocalMedCart.CertificateName));
myChannelFactory = new ChannelFactory<HIBridgeLib.HIBridgeService.IHIBridgeService>(basicHTTPBinding, endpointAddress);
myChannelFactory.Credentials.UserName.UserName = "username";
HIBridgeService = myChannelFactory.CreateChannel();
//do something
((IClientChannel)HIBridgeService).Close();
myChannelFactory.Close();
What is causing the error? 是什么导致错误?
It sounds like you are specifically targeting the basicHttpBinding
of the service. 听起来您似乎专门针对该服务的
basicHttpBinding
。 So, the wsHttpBinding
settings are irrelevant, as is the MessageSecurityValidator
class. 因此,
wsHttpBinding
设置与MessageSecurityValidator
类无关。 In general, your client-side settings should match the server-side settings, which use transport
security with a client credential certificate . 通常,您的客户端设置应与服务器设置匹配,服务器设置使用带有客户端证书证书的
transport
安全性。 The user will be identified by this certificate as far as WCF is concerned. 就WCF而言,该证书将标识用户。 So, instead of trying to set a username, you need to ensure that you are using a valid, server-recognized certificate.
因此,您无需确保设置用户名,而是需要确保使用的是服务器认可的有效证书。 Unfortunately, I do not have quite enough information to troubleshoot exactly what is wrong with your certificate, but check that:
不幸的是,我没有足够的信息来对您的证书到底有什么问题进行疑难解答,但请检查一下:
myClient.ClientCredentials.ClientCertificate.SetCertificate(...)
to provide the certificate. myClient.ClientCredentials.ClientCertificate.SetCertificate(...)
来提供证书。 (The example service in the link uses wsHttpBinding
rather than basicHttpBinding
, but for this aspect of configuration, it should make no difference.) wsHttpBinding
而不是basicHttpBinding
,但是对于这方面的配置,它应该没有任何区别。) netsh http show sslcert
at an administrator command prompt on the web server to see whether Negotiate Client Certificate is enabled for the site. netsh http show sslcert
的输出,以查看是否为该站点启用了协商客户端证书。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.