WCF:未提供服务证书。在 ServiceCredentials 中指定服务证书

Posted

技术标签:

【中文标题】WCF:未提供服务证书。在 ServiceCredentials 中指定服务证书【英文标题】:WCF: The service certificate is not provided. Specify a service certificate in ServiceCredentials 【发布时间】:2012-03-24 21:13:12 【问题描述】:

我正在尝试创建一个使用 MembershipProvider 进行身份验证的 WCF 服务。因为它是一项内部服务,所以我目前对应用传输级安全性 (HTTPS) 不感兴趣,并且我想(暂时)在没有证书的情况下执行此操作。此外,这会使服务的推出变得复杂,我希望稍后再做。我已经构建了一个基本配置(即使没有配置 MembershipProvider,但 WCF 不断向我抛出以下异常:

未提供服务证书。指定服务证书 在 ServiceCredentials 中。

这是我的配置:

<system.serviceModel>
  <bindings>
    <ws2007HttpBinding>
      <binding name="Service1WS2007HttpBindingConfig">
        <security mode="Message">
          <transport clientCredentialType="None" />
          <message clientCredentialType="UserName" />
        </security>
      </binding>
    </ws2007HttpBinding>
  </bindings>
  <services>
    <service name="WcfService1.Service1">
      <endpoint address="http://localhost:9800/Service1.svc"
        binding="ws2007HttpBinding"
        bindingConfiguration="Service1WS2007HttpBindingConfig"
        contract="WcfService1.IService1" />
    </service>
  </services>
  <behaviors>
    <serviceBehaviors>
      <behavior name="">
        <serviceMetadata httpGetEnabled="true" httpsGetEnabled="false" />
        <serviceDebug includeExceptionDetailInFaults="false" />
      </behavior>
    </serviceBehaviors>
  </behaviors>
  <serviceHostingEnvironment multipleSiteBindingsEnabled="false">
    <serviceActivations>
      <add relativeAddress="Service1.svc" service="WcfService1.Service1" />
    </serviceActivations>
  </serviceHostingEnvironment>
</system.serviceModel>

异常的堆栈跟踪:

[InvalidOperationException:未提供服务证书。 在 ServiceCredentials 中指定服务证书。 ] System.ServiceModel.Security.ServiceCredentialsSecurityTokenManager.CreateServerX509TokenProvider() +12382737 System.ServiceModel.Security.ServiceCredentialsSecurityTokenManager.CreateLocalSecurityTokenProvider(RecipientServiceModelSecurityTokenRequirement 收件人要求)+63 System.ServiceModel.Security.ServiceCredentialsSecurityTokenManager.CreateSecurityTokenProvider(SecurityTokenRequirement 要求)+48 System.ServiceModel.Security.ServiceCredentialsSecurityTokenManager.CreateTlsnegoServerX509TokenProvider(RecipientServiceModelSecurityTokenRequirement 收件人要求)+191 System.ServiceModel.Security.ServiceCredentialsSecurityTokenManager.CreateTlsnegoSecurityTokenAuthenticator(RecipientServiceModelSecurityTokenRequirement recipientRequirement, Boolean requireClientCertificate, SecurityTokenResolver&sctResolver) +683 System.ServiceModel.Security.ServiceCredentialsSecurityTokenManager.CreateSecurityTokenAuthenticator(SecurityTokenRequirement tokenRequirement, SecurityTokenResolver& outOfBandTokenResolver) +12383208 System.ServiceModel.Security.SessionRenewSecurityTokenManager.CreateSecurityTokenAuthenticator(SecurityTokenRequirement tokenRequirement、SecurityTokenResolver& outOfBandTokenResolver) +81 System.ServiceModel.Security.SymmetricSecurityProtocolFactory.OnOpen(时间跨度 超时)+181 System.ServiceModel.Security.WrapperSecurityCommunicationObject.OnOpen(时间跨度 超时)+21 System.ServiceModel.Channels.CommunicationObject.Open(时间跨度 超时)+318 System.ServiceModel.Security.SecurityListenerSettingsLifetimeManager.Open(时间跨度 超时)+94 System.ServiceModel.Channels.SecurityChannelListener`1.OnOpen(时间跨度 超时)+240 System.ServiceModel.Channels.CommunicationObject.Open(时间跨度 超时)+318 System.ServiceModel.Dispatcher.ChannelDispatcher.OnOpen(时间跨度 超时)+72

[InvalidOperationException:ChannelDispatcher 位于 带有合同的“http://localhost:9800/Service1.svc” '"IssueAndRenewSession"' 无法打开其 IChannelListener。] System.ServiceModel.Dispatcher.ChannelDispatcher.OnOpen(时间跨度 超时)+118 System.ServiceModel.Channels.CommunicationObject.Open(时间跨度 超时)+318 System.ServiceModel.ServiceHostBase.OnOpen(时间跨度 超时)+111 System.ServiceModel.Channels.CommunicationObject.Open(时间跨度 超时)+318 System.ServiceModel.Security.SecuritySessionSecurityTokenAuthenticator.OnOpen(时间跨度 超时)+131 System.ServiceModel.Security.WrapperSecurityCommunicationObject.OnOpen(时间跨度 超时)+21 System.ServiceModel.Channels.CommunicationObject.Open(时间跨度 超时)+318 System.ServiceModel.Security.CommunicationObjectSecurityTokenAuthenticator.Open(时间跨度 超时)+20 System.ServiceModel.Security.SecuritySessionServerSettings.OnOpen(时间跨度 超时)+792 System.ServiceModel.Security.WrapperSecurityCommunicationObject.OnOpen(时间跨度 超时)+21 System.ServiceModel.Channels.CommunicationObject.Open(时间跨度 超时)+318 System.ServiceModel.Security.SecurityListenerSettingsLifetimeManager.Open(时间跨度 超时)+148 System.ServiceModel.Channels.SecurityChannelListener`1.OnOpen(时间跨度 超时)+240 System.ServiceModel.Channels.CommunicationObject.Open(时间跨度 超时)+318 System.ServiceModel.Dispatcher.ChannelDispatcher.OnOpen(时间跨度 超时)+72

[InvalidOperationException:ChannelDispatcher 位于 带有合同“IService1”的“http://localhost:9800/Service1.svc”是 无法打开其 IChannelListener。] System.ServiceModel.Dispatcher.ChannelDispatcher.OnOpen(时间跨度 超时)+118 System.ServiceModel.Channels.CommunicationObject.Open(时间跨度 超时)+318 System.ServiceModel.ServiceHostBase.OnOpen(时间跨度 超时)+111 System.ServiceModel.Channels.CommunicationObject.Open(时间跨度 超时)+318 System.ServiceModel.HostingManager.ActivateService(字符串 标准化虚拟路径)+206 System.ServiceModel.HostingManager.EnsureServiceAvailable(字符串 normalizedVirtualPath) +651

[ServiceActivationException: 服务 '/Service1.svc' 不能 由于编译期间的异常而激活。例外 消息是:ChannelDispatcher 在 带有合同“IService1”的“http://localhost:9800/Service1.svc”是 无法打开其 IChannelListener..] System.Runtime.AsyncResult.End(IAsyncResult 结果) +688590 System.ServiceModel.Activation.HostedHttpRequestAsyncResult.End(IAsyncResult 结果)+190 System.ServiceModel.Activation.HostedHttpRequestAsyncResult.ExecuteSynchronous(HttpApplication 上下文,字符串 routeServiceVirtualPath,布尔值 flowContext,布尔值 确保WFService) +234 System.ServiceModel.Activation.HttpModule.ProcessRequest(对象 发件人,EventArgs e) +359 System.Web.SyncEventExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +148 System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +75

我的配置有什么问题,我该如何解决?

【问题讨论】:

This blog post 给出了答案。 见webservices20.blogspot.nl/2008/11/… 我猜你不想完全禁用安全性(当然是暂时的)?如果这样做,您将禁用 wshttp 绑定上的消息安全性,如下所示:&lt;security mode="None"&gt; 【参考方案1】:

您需要使用证书对服务进行签名。您可以通过将以下内容添加到配置中来做到这一点:

<serviceBehaviors>
    <behavior name="">
        <serviceMetadata httpGetEnabled="true" httpsGetEnabled="false" />
        <serviceDebug includeExceptionDetailInFaults="false" />

        *<serviceCredentials>
            <serviceCertificate findValue="certificatename" storeLocation="LocalMachine" storeName="My" x509FindType="FindBySubjectName" />
        </serviceCredentials>*
     </behavior>
</serviceBehaviors>

其中 certificatename 是您的证书的名称。要创建证书,您可以查看此处: Create a self signed certificate

【讨论】:

因为它是一项内部服务,我目前对应用传输级安全性不感兴趣,也不想创建证书,因为这会使服务的推出变得复杂。我可以在没有证书的情况下进行配置吗? 不,不幸的是,您必须创建证书,即使是用于内部测试。您可以创建自己的根级别证书颁发机构证书,然后使用它为您的服务颁发第二个证书。两者都需要安装在您推出的每台服务器上。 即使存在此证书,我仍然会收到此错误。什么给了? 您找到问题了吗?我也有类似的问题

以上是关于WCF:未提供服务证书。在 ServiceCredentials 中指定服务证书的主要内容,如果未能解决你的问题,请参考以下文章

在 HTTPS 情况下,未使用 HTTP.SYS 正确配置服务器证书

WCF 客户端证书停止工作

如何使用 WCF 签署 X509 令牌

WCF 身份验证错误

WCF 服务中的自定义客户端证书和用户名验证

WCF 服务 - 具有用户名身份验证的证书和消息安全性