客户端身份验证方案' Anonymous'禁止HTTP请求。远程服务器返回错误:(403)禁止

时间:2014-10-02 20:29:39

标签: c# wcf iis ssl

我正在尝试创建一个安全的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;
    }
}

这里我有服务代码

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();

这是客户端代码

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();

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

enter image description here

我的受信任根目录中的CA和TrustedPeople存储中的服务器/客户端证书。此外,如果我从浏览器导航到该网站,我会看到返回的页面。没有错误enter image description here

我已将IIS更新为我认为必需的,将证书绑定在IIS中 enter image description here

并通过下面的命令行。 enter image description here

我已将SSL设置设置为接受证书 enter image description here

并启用匿名身份验证。 enter image description here

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

5 个答案:

答案 0 :(得分:1)

另一个原因是您正在服务的服务器上的证书本身。确保已导入PRIVATE KEY。在MMC中,这将显示一个&#34;友好名称&#34;。这花了我几天才弄明白。一旦我导入私钥,匿名错误消失了,一切都很好!

答案 1 :(得分:0)

在IIS中使用安全类型传输和客户端凭据类型证书托管WCF服务时,将您的客户端证书放在根存储上并在IIS中启用匿名身份验证Enable anonymous authentication in IIS. But most importantly, add your certificate to root store.

答案 2 :(得分:0)

如果您运行自托管WCF服务(没有IIS),您可以通过向confing文件(在服务器中)添加以下内容来启用匿名客户端:

<behaviors>
    <serviceBehaviors>
        <behavior name="limitedAuthBehavior">
            <serviceAuthenticationManager authenticationSchemes="Anonymous, Basic, Digest, Negotiate"/>
            <!-- ... -->
        </behavior>
    </serviceBehaviors>
</behaviors>

另外,将clientCredentialType设置为&#34; InheritedFromHost&#34;:

<bindings>
      <basicHttpBinding>
        <binding name="secureBinding">
          <security mode="Transport">
            <transport clientCredentialType="InheritedFromHost" />
          </security>
        </binding>
      </basicHttpBinding>
</bindings>

参考文献:

Using Multiple Authentication Schemes with WCF

Understanding HTTP Authentication

答案 3 :(得分:0)

我们收到了此错误消息,对于我们来说,解决方案是没有为脚本启用Handler Mappings功能权限。您可以在Handler Mappings&gt;下的IIS中启用它。编辑功能权限,或将Script添加到web.config中accessPolicy节点的handlers属性:

<system.webServer>
  <handlers accessPolicy="Script">
    ...
  </handlers>
</system.webServer>

答案 4 :(得分:0)

我有这种错误。该证书是一个子域通配符。我必须将私钥导入LocalMachine的“受信任的人”存储中,该错误消失了。就像其他人指出的那样,您也可以尝试将私钥导入LocalMachine的“受信任的根”存储中。