客户端身份验证方案"匿名"禁止HTTP请求.远程服务器返回错误:(403)禁止

fan*_*bob 11 c# iis ssl wcf

我正在尝试创建一个安全的Web服务.

这是合同和服务实施

[ServiceContract()]
public interface ICalculatorService
{
    [OperationContract()]
    int Add(int x, int y);
}

[ServiceBehavior(IncludeExceptionDetailInFaults=true)]
public class CalculatorService : ICalculatorService
{
    public int Add(int x, int y)
    {
        return x + y;
    }
}
Run Code Online (Sandbox Code Playgroud)

这里我有服务代码

var b = new WSHttpBinding(SecurityMode.Transport);
b.Security.Transport.ClientCredentialType = HttpClientCredentialType.Certificate;
b.Security.Message.ClientCredentialType = MessageCredentialType.None;

Type contractType = typeof(ICalculatorService);
Type implementedContract = typeof(CalculatorService);
Uri baseAddress = new Uri("https://localhost:8006/CalculatorService");
ServiceHost sh = new ServiceHost(implementedContract);

sh.AddServiceEndpoint(contractType, b, baseAddress);

//ServiceMetadataBehavior sm = new ServiceMetadataBehavior();
//sm.HttpsGetEnabled = true;
//sm.HttpsGetUrl = new Uri("https://localhost:8006/CalculatorServiceMex");
//sh.Description.Behaviors.Add(sm);

sh.Credentials.Peer.PeerAuthentication.CertificateValidationMode = System.ServiceModel.Security.X509CertificateValidationMode.PeerTrust;
        sh.Credentials.ServiceCertificate.SetCertificate(StoreLocation.LocalMachine, StoreName.TrustedPeople, X509FindType.FindBySubjectName, "localhost");

sh.Open();
Console.WriteLine("Service is Listening");
Console.ReadLine();
sh.Close();
Run Code Online (Sandbox Code Playgroud)

这是客户端代码

var b = new WSHttpBinding(SecurityMode.Transport);
b.Security.Transport.ClientCredentialType = HttpClientCredentialType.Certificate;
b.Security.Message.ClientCredentialType = MessageCredentialType.None;

var factory = new ChannelFactory<ICalculatorService>(b);
factory.Credentials.Peer.PeerAuthentication.CertificateValidationMode = System.ServiceModel.Security.X509CertificateValidationMode.PeerTrust;
        factory.Credentials.ClientCertificate.SetCertificate(StoreLocation.LocalMachine, StoreName.TrustedPeople, X509FindType.FindBySubjectName, "localhost");

var client = factory.CreateChannel(new EndpointAddress(new Uri("https://localhost:8006/CalculatorService")));

ServicePointManager.ServerCertificateValidationCallback =
   ((sender, certificate, chain, sslPolicyErrors) =>
            {
                return true;
            });

ICommunicationObject comObject = client as ICommunicationObject;
int result = -1;
try
{
  comObject.Open();
  result = client.Add(10, 2);
}
catch (Exception ex)
{

}
Console.WriteLine(string.Format("Service say 10 + 2 = {0}", -1));
Console.ReadLine();
Run Code Online (Sandbox Code Playgroud)

该服务运行正常,并且在进行ServicePointManager.ServerCertificateValidationCallback检查时,没有策略错误,并且构建了正确的证书链.

在此输入图像描述

我在受信任的根中有我的CA,在TrustedPeople商店中有服务器/客户端证书.此外,如果我从浏览器导航到该网站,我会看到返回的页面.没有错误在此输入图像描述

我已经将IIS更新为我认为必需的,将证书绑定在IIS中 在此输入图像描述

并通过下面的命令行. 在此输入图像描述

我已将SSL设置设置为接受证书 在此输入图像描述

并启用匿名身份验证. 在此输入图像描述

有谁知道我没有正确完成哪些步骤或看到有什么不妥之处?我一直收到同样的错误"HTTP请求被禁止使用客户端身份验证方案'匿名'."

小智 5

另一个原因是您所访问的服务器上的证书本身。确保您已导入私钥。在 MMC 中,这将显示为“友好名称”。这花了我几天的时间才弄清楚。一旦我导入私钥,匿名错误就消失了,一切都很好!


fan*_*bob 0

有一个注册表项位于HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL。设置该值可以0解决问题。此处概述了一些其他潜在的解决方案。我有一个现有的答案,它引用了方法 3,并从引用的页面获得了许多赞成票,但由于未知原因被版主删除了。重新发布以防将来对其他人有帮助。