2017-10-16 3 views
0

ich, dieses Handbuch nach einem WCF-Dienst mit zertifikatsbasierter Authentifizierung einzurichten versuchen: https://msdn.microsoft.com/en-au/library/ff648360.aspx?f=255&MSPPError=-2147217396WCF-Dienst mit Zertifikatsauthentifizierung: „Der Anrufer nicht vom Dienst authentifiziert wurde“

Ich folgte habe alle Schritte (glaube ich), die zusammenfassend sind:
1) generiert ein selbst signiertes CA-Zertifikat und installiert es als Computerebene vertrauenswürdige CA:

enter image description here

2) ein Zertifikat für den Dienst generiert (vom CA-Zertifikat signiert, CN=QvxServiceCert) und installiert sie auf Maschinenebene:

enter image description here

3) konfiguriert ist, das Zertifikat des WCF-Service Endpunkt-Verhalten zu verwenden. Meine Service-Konfiguration sieht wie folgt aus:

<?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) ein Zertifikat für den Client generiert (wieder durch das CA-Zertifikat signiert, das hat man CN=QvxClientCert) und auf Benutzerebene installiert:

enter image description here

5) das Verhalten des WCF-Clients so konfiguriert, dass es zur Authentifizierung verwendet wird. Das ist mein Client config:

<?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) gab dem Benutzer, der die Client-Zugriff auf das Zertifikat ausgeführt wird, indem Sie das folgende in der Befehlszeile eingeben: cacls "C:\Users\MyUsername\AppData\Roaming\Microsoft\Crypto\RSA\S-1-5-21-742627442-1779984360-2302642487-1000" /E /G "MyUser-PC\MyUsername":R

Dies alles wurde nach dem Reiseleiter, ohne jedes Problem, das ich sehen konnte. Alles scheint in Ordnung ... aber wenn ich versuche, den Dienst von meinem Client aufrufen, alles, was ich diese frustrierende vage und wenig hilfreich Ausnahme erhalten:

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) 

Antwort

0

Nun, nach viel Versuch und Irrtum, stellt sich heraus, dass Sie entweder für Ihre CA oder Sie haben eine CRL müssen explizit installiert haben, dass Sie nicht über eine Sperrungsüberprüfung mögen, indem das Hinzufügen dieser zu Ihrem Verhalten ClientCredentials Tag angeben:

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

und umgekehrt für die Serviceseite:

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

Sie müssen auch das automatisch generierte Zertifikat-Tag im Client entfernen und es durch eine Anweisung zum Nachschlagen des Zertifikats ersetzen:

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