2017-10-16 193 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>