Mutual Authentication in a Windows Sockets Service with an
SCP
This section includes a code example that shows how to perform
mutual authentication with a service that publishes itself using a
service connection point (SCP). The code 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; an exception is that a service running
under the LocalSystem account can register its SPN in the form
ServiceClass/Host on the computer account of the
service host.
To verify
configuration at service startup
Verify that the appropriate SPNs are registered on the account
under which the service is running. For more information, see
Logon Account
Maintenance Tasks.
To authenticate
the service at client startup
Retrieve connection data from the service's service 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 data retrieved from the service
connection point. This data includes the host name of the server on
which the service is running. Be aware 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 stringent, you should also use
encryption. For more information and a code example 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 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 and encryption unless
performance is an issue.
The following topics provide a code example for this mutual
authentication scenario: