Some people asked me some interesting question about authenticating of client at the service side but without of authenticating of service at the client side. Personally, I do not see why it should be important in the productive environment to avoid authentication of the service at the client side? I would find it pretty risky, because this feature prevents client of phishing (even if the service is in intranet=>quasi-trusted zone).
Assuming that out there in universe there is some reason for this, I build an example which shows how to do this. First of all take a look on following service configuration, which shows how to enforce service to send the certificate to the client. Additionally this configuration verifies the client's certificate is in the TrustedPeople certificate store or by building a certificate trust chain.
PeereORChainTrust is setup for validation of the client's certificate. ServiceCertificate node is the certificate which will be sent by service to the client. This certificate protects the client form phishing.
Analog to service the client configuration which sends the client's specific certificate and authenticates the service looks like:
Then following class should be implemented, which provides a custom certificate authentication. The class should be
implemented at the client's side. Return means all service certificates are by default valid.
public class CustomX509CertificateValidator : X509CertificateValidator {
// This Validation function accepts any X509 Certificate
public override void Validate(X509Certificate2 certificate)
{
return;
}
}
Last but not least, change the client's configuration to use CustomX509CertificateValidator as shown at the picture below:
<behaviors>
<endpointBehaviors>
<behavior name="ClientCertificateBehavior">
<clientCredentials>
<clientCertificate findValue="localhost" storeLocation="LocalMachine"
storeName="My" x509FindType="FindBySubjectName" />
<serviceCertificate>
<authentication certificateValidationMode="Custom"
customCertificateValidatorType=
"Microsoft.ServiceModel.Samples.CustomX509CertificateValidator, service" />
</serviceCertificate>
</clientCredentials>
</behavior>
</endpointBehaviors>
</behaviors>
Related posts:
http://developers.de/blogs/damir_dobric/archive/2006/10/01/935.aspx
http://developers.de/blogs/damir_dobric/archive/2006/09/24/931.aspx
Code hidden in pictures:
configuration for first picture:
<?xml version="1.0" encoding="utf-8" ?> <configuration> <system.serviceModel> <services> <service name="Microsoft.ServiceModel.Samples.CalculatorService" behaviorConfiguration="CalculatorServiceBehavior"> <!-- use host/baseAddresses to configure base address provided by host --> <host> <baseAddresses> <add baseAddress ="http://localhost:8001/servicemodelsamples/service" /> </baseAddresses> </host> <!-- use base address specified above, provide one endpoint --> <endpoint address="certificate" binding="wsHttpBinding" bindingConfiguration="Binding" contract="Microsoft.ServiceModel.Samples.ICalculator" /> </service> </services> <bindings> <wsHttpBinding> <binding name="Binding"> <security mode="Message"> <message clientCredentialType="Certificate" /> </security> </binding> </wsHttpBinding> </bindings> <behaviors> <serviceBehaviors> <behavior name="CalculatorServiceBehavior"> <serviceDebug includeExceptionDetailInFaults ="true"/> <serviceCredentials> <!-- The serviceCredentials behavior allows one to specify authentication constraints on client certificates. --> <clientCertificate> <authentication certificateValidationMode="PeerOrChainTrust" /> </clientCertificate> <serviceCertificate findValue="localhost" storeLocation="LocalMachine" storeName="My" x509FindType="FindBySubjectName" /> </serviceCredentials> </behavior> </serviceBehaviors> </behaviors> </system.serviceModel> </configuration> |
Configuration for second picture:
<?xml version="1.0" encoding="utf-8" ?> <configuration> <system.serviceModel> <client> <!-- X509 certificate based endpoint --> <endpoint name="Certificate" address="http://localhost:8001/servicemodelsamples/service/certificate" binding="wsHttpBinding" bindingConfiguration="Binding" behaviorConfiguration="ClientCertificateBehavior" contract="Microsoft.ServiceModel.Samples.ICalculator"> </endpoint> </client> <bindings> <wsHttpBinding> <!-- X509 certificate binding --> <binding name="Binding"> <security mode="Message"> <message clientCredentialType="Certificate" /> </security> </binding> </wsHttpBinding> </bindings> <behaviors> <endpointBehaviors> <behavior name="ClientCertificateBehavior"> <clientCredentials> <clientCertificate findValue="localhost" storeLocation="LocalMachine" storeName="My" x509FindType="FindBySubjectName" /> <serviceCertificate> <authentication certificateValidationMode="PeerOrChainTrust" /> </serviceCertificate> </clientCredentials> </behavior> </endpointBehaviors> </behaviors> </system.serviceModel> </configuration> |
Posted
Oct 18 2008, 01:03 AM
by
Damir Dobric