Mutual Authentication in a Windows Sockets Service with an SCP
This section provides sample code that shows how to perform mutual authentication with a service that publishes itself using a service connection point (SCP). The example is based on a Microsoft® Windows® Sockets service that uses an SSPI package to handle the mutual authentication negotiation between a client and the service.
The example follows these steps to implement mutual authentication:
To register SPNs in the directory at service installation
- Call the DsGetSpn function to compose service principal names (SPNs) for the service.
- Call the DsWriteAccountSpn function to register the SPNs on the service account or computer account in whose context the service will run. This step must be performed by a domain administrator (except that a service running under the LocalSystem account can register its SPN in the form ServiceClass/Host on the computer account of the service's host).
To verify configuration at service startup
Verify that the appropriate SPNs are registered on the account under which the service is running. See Logon Account Maintenance Tasks.
To authenticate the service at client startup
- Retrieve connection information from the service's connection point.
- Establish a connection to the service.
- Call the DsMakeSpn function to compose an SPN for the service. Compose the SPN from the known service class string, and the information retrieved from the service connection point. This information includes the host name of the server on which the service is running. Note that the host name must be a DNS name.
- Use an SSPI security package to perform the authentication.
- Call the AcquireCredentialsHandle function to acquire the client's credentials.
- Pass the client credentials and the SPN to the InitializeSecurityContext function to generate a security blob to send to the service for authentication. Set the ISC_REQ_MUTUAL_AUTH flag to request mutual authentication.
- Exchange blobs with the service until the authentication is complete.
- Check the returned capabilities mask for the ISC_RET_MUTUAL_AUTH flag to verify that mutual authentication was performed.
- If the authentication was successful, exchange traffic with the authenticated service. Use digital signing to ensure that messages between client and service have not been tampered with. Unless performance requirements are very stringent, you should also use encryption. For sample code that illustrates the use of the MakeSignature, VerifySignature, EncryptMessage, and DecryptMessage functions in an SSPI package, see Ensuring Communication Integrity During Message Exchange in the SSPI documentation.
To authenticate the client by the service when a client connects
- Load an SSPI security package that supports mutual authentication.
- When a client connects, use the security package to perform the authentication.
- Call the AcquireCredentialsHandle function to acquire the service's credentials.
- Pass the service credentials and the security blob received from the client to the AcceptSecurityContext function to generate a security blob to send back to the client.
- Exchange blobs with the client until the authentication is complete.
- Check the returned capabilities mask for the ASC_RET_MUTUAL_AUTH flag to verify that mutual authentication was performed.
- If the authentication was successful, exchange traffic with the authenticated client. Use digital signing. Use encryption as well, unless performance is an issue.
The following topics provide sample code for this mutual authentication scenario.
For more information, see the following topics: