首页 > 解决方案 > 使用带有 x509 证书的 IIS 托管 WCF 服务进行身份验证

问题描述

我有一个通过 https 托管在 IIS 中的 Web 服务。我能够从测试客户端应用程序连接到服务并返回结果。

我想查看请求中使用的证书,但服务器似乎没有这方面的记录。

我正在按照此处定义的方式执行 basicHttpBinding:

    <basicHttpBinding>
        <binding name="basicHttpBinding">
            <security mode="Transport" />
        </binding>
    </basicHttpBinding>

在客户端代码中创建本地服务代理时,我因此附加了一个 x509 证书,其中 userCerts 是本地证书存储中证书的非空列表

        var service = new WcfBasicServiceClient();
        service.ClientCredentials.ClientCertificate.Certificate = userCerts[0];

        double randomDouble = service.GetRandomDouble();

再次,呼叫通过服务。在服务器端,我正在尝试检查使用的证书。但是,这ServiceSecurityContext.Current.PrimaryIdentity是一个通用身份。此外, theOperationContext.Current.ServiceSecurityContext.AuthorizationContext.ClaimSets是一个空集。就好像服务器不知道所使用的证书一样。

           var securityContext = ServiceSecurityContext.Current;
            var primaryIdentity = securityContext.PrimaryIdentity;


            Logger.Info("Primary Identity: " + primaryIdentity);
            Logger.Info("auth type: " + primaryIdentity.AuthenticationType);
            Logger.Info("name: " + primaryIdentity.Name);


            // gets an empty list here
            // https://stackoverflow.com/a/7528703/680268
            if (OperationContext.Current.ServiceSecurityContext.AuthorizationContext.ClaimSets == null)
            {
                Logger.Warn("claimset service configured wrong");
                return;
            }

            if (OperationContext.Current.ServiceSecurityContext.AuthorizationContext.ClaimSets.Count <= 0)
            {
                Logger.Warn("claimset empty - service configured wrong");
                return;
            }


            var cert = ((X509CertificateClaimSet)OperationContext.Current.ServiceSecurityContext.
                AuthorizationContext.ClaimSets[0]).X509Certificate;

            Logger.Info("cert serial num: " + cert.SerialNumber);
            Logger.Info("subj name: " + cert.SubjectName);
            Logger.Info("thumb print: " + cert.Thumbprint);

另外,在 IIS 网站设置中,我在 SSL 设置下设置了“接受”,但没有启用“需要 SSL”。

我的服务有什么错误配置,它不接受客户端请求中的 x509 证书?

这是我的服务的 web.config:

     <system.serviceModel>
    <bindings>
      <basicHttpBinding>
        <binding name="httpsBinding" allowCookies="true" maxReceivedMessageSize="2147483647" maxBufferPoolSize="2147483647">
          <readerQuotas maxDepth="2147483647" maxStringContentLength="2147483647" maxArrayLength="2147483647" maxBytesPerRead="2147483647" maxNameTableCharCount="2147483647" />
          <security mode="Transport">
            <transport clientCredentialType="None" />
          </security>
        </binding>
      </basicHttpBinding>
    </bindings>

    <services>
      <service name="WcfServiceLibrary1.WcfBasicService">
        <endpoint address="" binding="basicHttpBinding" contract="WcfServiceLibrary1.IWcfBasicService" name="basicHttpBinding" bindingConfiguration="httpsBinding">
          <identity>
            <dns value="localhost" />
          </identity>
        </endpoint>

        <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />

      </service>
    </services>
    <behaviors>
      <serviceBehaviors>
        <behavior>
          <!-- To avoid disclosing metadata information, 
          set the values below to false before deployment -->
          <serviceMetadata httpGetEnabled="True" httpsGetEnabled="True" />
          <!-- To receive exception details in faults for debugging purposes, 
          set the value below to true.  Set to false before deployment 
          to avoid disclosing exception information -->
          <serviceDebug includeExceptionDetailInFaults="True" />
        </behavior>
      </serviceBehaviors>
    </behaviors>
  </system.serviceModel>

编辑,我更新了我的 web.config 和 app.config 以指定证书的客户端凭据类型,但是尝试在客户端上进行调用时出现如下错误:

    ErrorSystem.ServiceModel.Security.MessageSecurityException: The HTTP request was forbidden with client authentication scheme 'Anonymous'. ---> System.Net.WebException: The remote server returned an error: (403) Forbidden.
   at System.Net.HttpWebRequest.GetResponse()
   at System.ServiceModel.Channels.HttpChannelFactory`1.HttpRequestChannel.HttpChannelRequest.WaitForReply(TimeSpan timeout)
   --- End of inner exception stack trace ---

Server stack trace:
   at System.ServiceModel.Channels.HttpChannelUtilities.ValidateAuthentication(HttpWebRequest request, HttpWebResponse response, WebException responseException, HttpChannelFactory`1 factory)
   at System.ServiceModel.Channels.HttpChannelUtilities.ValidateRequestReplyResponse(HttpWebRequest request, HttpWebResponse response, HttpChannelFactory`1 factory, WebException responseException, ChannelBinding channelBinding)

标签: c#wcfx509certificate

解决方案


推荐阅读