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

Posted

技术标签:

【中文标题】客户端身份验证方案“匿名”禁止 HTTP 请求。远程服务器返回错误:(403) Forbidden【英文标题】:The HTTP request was forbidden with client authentication scheme 'Anonymous'. The remote server returned an error: (403) Forbidden 【发布时间】:2014-11-27 22:23:21 【问题描述】:

我正在尝试创建一个安全的网络服务。

这里是合约和服务实现

[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 检查时没有策略错误,并构建了正确的证书链。

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

我已将 IIS 更新为我认为需要的,将证书绑定在 IIS 中

并通过下面的命令行。

我已将 SSL 设置设置为接受证书

并启用匿名身份验证。

有谁知道我没有正确执行哪些步骤或发现有什么问题?我不断收到相同的错误“客户端身份验证方案‘匿名’禁止 HTTP 请求。”

【问题讨论】:

我遇到了这个异常,但这是由于我的 ssl 证书过期。 WCF 是否有 IIS 的替代方案。我讨厌 IIS,前一天它可以工作,下一天它开始出现各种错误,需要一整天才能解决。 【参考方案1】:

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

【讨论】:

【参考方案2】:

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

【讨论】:

【参考方案3】:

我们收到此错误消息,对我们而言,解决方案是未为脚本启用处理程序映射功能权限。您可以在 IIS 中的 Handler Mappings > Edit Feature Permissions 下启用此功能,或者将 Script 添加到 web.config 中 handlers 节点的 accessPolicy 属性:

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

【讨论】:

【参考方案4】:

如果您运行自托管 WCF 服务(不带 IIS),您只需将以下设置添加到配置文件(在服务器中)即可启用匿名客户端:

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

另外,将 clientCredentialType 设置为“InheritedFromHost”:

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

参考资料:

Using Multiple Authentication Schemes with WCF

Understanding HTTP Authentication

【讨论】:

【参考方案5】:

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

【讨论】:

以上是关于客户端身份验证方案“匿名”禁止 HTTP 请求。远程服务器返回错误:(403) Forbidden的主要内容,如果未能解决你的问题,请参考以下文章

重现问题:客户端身份验证方案“匿名”禁止 http 请求

收到 403 禁止错误。客户端身份验证方案“匿名”禁止 HTTP 请求

客户端身份验证方案“匿名”禁止 HTTP 请求

如何修复“客户端身份验证方案‘匿名’禁止 HTTP 请求”

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

添加 WCF 服务引用时,HTTP 请求被客户端身份验证方案“匿名”错误禁止