基本 HttpBinding 身份验证错误
本文关键字:错误 身份验证 HttpBinding 基本 | 更新日期: 2023-09-27 18:35:56
我是 Web 服务的
新手,我需要通过 C# 桌面应用程序的wsHttpsBinding
和basicHttpBinding
实现对现有 Web 服务的basicHttpBinding
。当我尝试将服务与桌面应用程序一起使用时,出现以下错误:
HTTP 请求被客户端身份验证方案"匿名"禁止。
Web 服务上包含basicHttpBinding
和wsHttpsBinding
的 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>
用户名身份验证如下所示:
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");
}
}
}
}
我的桌面应用程序代码如下所示以使用 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();
导致错误的原因是什么?
听起来
您专门针对服务basicHttpBinding
。 因此,wsHttpBinding
设置无关紧要,MessageSecurityValidator
类也是如此。 通常,客户端设置应与服务器端设置匹配,服务器端设置将transport
安全性与客户端凭据证书一起使用。 就 WCF 而言,用户将由此证书标识。 因此,您需要确保使用的是有效的、服务器识别的证书,而不是尝试设置用户名。 不幸的是,我没有足够的信息来准确解决您的证书问题,但请检查:
- 本地证书存储(在运行桌面应用程序的计算机上)实际上具有服务识别为有效的证书。
- 证书指定正确。 MSDN 建议提供证书的类似
myClient.ClientCredentials.ClientCertificate.SetCertificate(...)
。 (链接中的示例服务使用wsHttpBinding
而不是basicHttpBinding
,但对于配置的这一方面,它应该没有区别。 - 托管服务的 Web 服务器实际上是为客户端证书身份验证配置的。 一个参考建议在 Web 服务器上的管理员命令提示符下检查
netsh http show sslcert
的输出,以查看是否为站点启用了协商客户端证书。