2017-10-16 160 views
0

我试图建立与基于证书的验证WCF服务“对方不是由服务认证”,该指南如下:https://msdn.microsoft.com/en-au/library/ff648360.aspx?f=255&MSPPError=-2147217396WCF服务与证书认证:

我已经照着所有的步骤(我认为),这在总结如下:
1)生成的自签名CA证书并安装它作为一台机器级信任的CA:

enter image description here

2)生成服务证书(由CA证书签署,CN=QvxServiceCert),并在机器级安装了:

enter image description here

3)中配置的WCF服务端点行为使用的证书。我的服务配置是这样的:

<?xml version="1.0" encoding="utf-8"?> 
<configuration> 
    <startup> 
     <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.1" /> 
    </startup> 

    <system.serviceModel> 
    <bindings> 
     <wsHttpBinding> 
     <binding name="wsHttpEndpointBinding"> 
      <security> 
      <message clientCredentialType="Certificate" /> 
      </security> 
     </binding> 
     </wsHttpBinding> 
    </bindings> 
    <behaviors> 
     <serviceBehaviors> 
     <behavior name="QvxServiceBehavior"> 
      <serviceMetadata httpGetEnabled="true" httpsGetEnabled="true" /> 
      <serviceDebug includeExceptionDetailInFaults="true" /> 
      <serviceCredentials> 
      <serviceCertificate findValue="CN=QvxServiceCert" /> 
      </serviceCredentials> 
     </behavior> 
     </serviceBehaviors> 
    </behaviors> 
    <services> 
     <service name="esqQvxScheduler.Service.QvxSchedulerAPI" behaviorConfiguration="QvxServiceBehavior"> 
     <endpoint address="" binding="wsHttpBinding" bindingConfiguration="wsHttpEndpointBinding" 
      name="wsHttpEndpoint" bindingName="" contract="esqQvxScheduler.Service.IQvxSchedulerAPI" /> 
     <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" /> 
     <host> 
      <baseAddresses> 
      <add baseAddress="http://localhost:8733/QvxSchedulerAPI/" /> 
      </baseAddresses> 
     </host> 
     </service> 
    </services> 
    </system.serviceModel> 
</configuration> 

4)生成的证书对客户端(同样,由CA证书签署,这其中有CN=QvxClientCert),并在用户级安装:

enter image description here

5)配置WCF客户端行为以使用它进行身份验证。这是我的客户端配置:

<?xml version="1.0" encoding="utf-8" ?> 
<configuration> 
    <startup> 
     <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5.2" /> 
    </startup> 
    <system.serviceModel> 
     <behaviors> 
      <endpointBehaviors> 
       <behavior name="qvxClientBehavior"> 
        <clientCredentials> 
         <clientCertificate findValue="CN=QvxClientCert" /> 
        </clientCredentials> 
       </behavior> 
      </endpointBehaviors> 
     </behaviors> 
     <bindings> 
      <wsHttpBinding> 
       <binding name="wsHttpEndpoint"> 
        <security> 
         <message clientCredentialType="Certificate" /> 
        </security> 
       </binding> 
      </wsHttpBinding> 
     </bindings> 
     <client> 
      <endpoint address="http://localhost:8733/QvxSchedulerAPI/" binding="wsHttpBinding" behaviorConfiguration="qvxClientBehavior" 
       bindingConfiguration="wsHttpEndpoint" contract="QvxSchedulerAPI.IQvxSchedulerAPI" 
       name="wsHttpEndpoint"> 
       <identity> 
        <certificate encodedValue="[A LONG AUTOGENERATED STRING THE MEANING OF WHICH I HAVE NO IDEA]" /> 
       </identity> 
      </endpoint> 
     </client> 
    </system.serviceModel> 
</configuration> 

6)给了运行到该证书的客户端访问,通过发出命令行上输入以下用户:cacls "C:\Users\MyUsername\AppData\Roaming\Microsoft\Crypto\RSA\S-1-5-21-742627442-1779984360-2302642487-1000" /E /G "MyUser-PC\MyUsername":R

这是所有做指导下,无任何我能看到的问题。一切似乎都OK ...但是当我尝试从我的客户端调用服务,我得到这个令人沮丧的含糊和无益的例外:要么

Unhandled Exception: System.ServiceModel.Security.SecurityNegotiationException: The caller was not authenticated by the service. ---> System.ServiceModel.FaultException: The request for security token could not be satisfied because authentication failed. 
    at System.ServiceModel.Security.SecurityUtils.ThrowIfNegotiationFault(Message message, EndpointAddress target) 
    at System.ServiceModel.Security.SspiNegotiationTokenProvider.GetNextOutgoingMessageBody(Message incomingMessage, SspiNegotiationTokenProviderState sspiState) 
    --- End of inner exception stack trace --- 

Server stack trace: 
    at System.ServiceModel.Security.IssuanceTokenProviderBase`1.DoNegotiation(TimeSpan timeout) 
    at System.ServiceModel.Security.SspiNegotiationTokenProvider.OnOpen(TimeSpan timeout) 
    at System.ServiceModel.Security.TlsnegoTokenProvider.OnOpen(TimeSpan timeout) 
    at System.ServiceModel.Security.WrapperSecurityCommunicationObject.OnOpen(TimeSpan timeout) 
    at System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout) 
    at System.ServiceModel.Security.CommunicationObjectSecurityTokenProvider.Open(TimeSpan timeout) 
    at System.ServiceModel.Security.SymmetricSecurityProtocol.OnOpen(TimeSpan timeout) 
    at System.ServiceModel.Security.WrapperSecurityCommunicationObject.OnOpen(TimeSpan timeout) 
    at System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout) 
    at System.ServiceModel.Channels.SecurityChannelFactory`1.ClientSecurityChannel`1.OnOpen(TimeSpan timeout) 
    at System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout) 
    at System.ServiceModel.Security.SecuritySessionSecurityTokenProvider.DoOperation(SecuritySessionOperation operation, EndpointAddress target, Uri via, SecurityToken currentToken, TimeSpan timeout) 
    at System.ServiceModel.Security.SecuritySessionSecurityTokenProvider.GetTokenCore(TimeSpan timeout) 
    at System.IdentityModel.Selectors.SecurityTokenProvider.GetToken(TimeSpan timeout) 
    at System.ServiceModel.Security.SecuritySessionClientSettings`1.ClientSecuritySessionChannel.OnOpen(TimeSpan timeout) 
    at System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout) 
    at System.ServiceModel.Channels.ServiceChannel.OnOpen(TimeSpan timeout) 
    at System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout) 
    at System.ServiceModel.Channels.ServiceChannel.CallOpenOnce.System.ServiceModel.Channels.ServiceChannel.ICallOnce.Call(ServiceChannel channel, TimeSpan timeout) 
    at System.ServiceModel.Channels.ServiceChannel.CallOnceManager.CallOnce(TimeSpan timeout, CallOnceManager cascade) 
    at System.ServiceModel.Channels.ServiceChannel.Call(String action, Boolean oneway, ProxyOperationRuntime operation, Object[] ins, Object[] outs, TimeSpan timeout) 
    at System.ServiceModel.Channels.ServiceChannelProxy.InvokeService(IMethodCallMessage methodCall, ProxyOperationRuntime operation) 
    at System.ServiceModel.Channels.ServiceChannelProxy.Invoke(IMessage message) 

回答

0

好,大量的试验和错误之后,原来你必须安装有您的CA CRL或你有加入这个自己的行为负责的ClientCredentials标签明确指出你不想吊销检查,:

<serviceCertificate> 
    <authentication revocationMode="NoCheck"/> 
</serviceCertificate> 

,反之亦然为服务端:

<clientCertificate> 
    <authentication certificateValidationMode="ChainTrust" revocationMode="NoCheck"/> 
</clientCertificate> 

此外,您需要删除客户端中的自动生成的证书标记并将其替换为查找证书的说明:

<identity> 
    <certificateReference findValue="CN=QvxServiceCert" x509FindType="FindBySubjectName" storeLocation="LocalMachine" storeName="My" /> 
</identity>