Reputation: 46410
I'm setting up client certificates on my wcf service. All works great. The service requires client certs, my client test app supplies the cert and is able to make a request to one of the service end points.
No I want to implement a custom validator. I created a new class inheriting from X509CertificateValidator, and set it up in the services web config. I can put a breakpoint in the validate method and see it gets called. Awesome possum.
Now I want to be able to supply custom configuration parameters to the validator. The X509CertificateValidator has a LoadCustomConfiguration method which I can override, but it doesn't get called, I'm assuming it's because I'm not supplying any actual custom configuration anywhere - if that assumption is correct, how do I define my custom configuration parameters? Or is there some other way I should be doing this?
public class CustomValidator : System.IdentityModel.Selectors.X509CertificateValidator
{
/// <summary>
/// If the passed certificate is not valid according to the validation logic, this method throws a SecurityTokenValidationException. If the certificate is valid, the method returns to the caller.
/// </summary>
/// <param name="certificate"></param>
public override void Validate(System.Security.Cryptography.X509Certificates.X509Certificate2 certificate)
{
bool bValid = true;
// Check that there is a certificate.
if (certificate == null)
{
throw new ArgumentNullException("certificate", "Certificate was not supplied.");
}
bValid = certificate.Verify() &&
DateTime.Now <= certificate.NotAfter &&
DateTime.Now >= certificate.NotBefore;
if (!bValid)
{
throw new System.IdentityModel.Tokens.SecurityTokenValidationException("Certificate is not valid.");
}
}
public override void LoadCustomConfiguration(System.Xml.XmlNodeList nodelist)
{
base.LoadCustomConfiguration(nodelist);
}
}
Configuration
<?xml version="1.0"?>
<configuration>
<appSettings>
<add key="aspnet:UseTaskFriendlySynchronizationContext" value="true" />
</appSettings>
<system.web>
<compilation debug="true" targetFramework="4.5" />
<httpRuntime targetFramework="4.5"/>
</system.web>
<system.serviceModel>
<services>
<service name="WCFTransportAuthCertificateCustomValidation.Service1"
behaviorConfiguration="MapClientCertificates">
<endpoint binding="basicHttpBinding"
bindingConfiguration="TransportCertificateAuthentication"
contract="WCFTransportAuthCertificateCustomValidation.IService1">
</endpoint>
</service>
</services>
<bindings>
<basicHttpBinding>
<binding name="TransportCertificateAuthentication">
<security mode="Transport">
<transport clientCredentialType="Certificate"></transport>
</security>
</binding>
</basicHttpBinding>
</bindings>
<behaviors>
<serviceBehaviors>
<behavior>
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="false"/>
</behavior>
<behavior name="MapClientCertificates">
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="false"/>
<serviceCredentials>
<clientCertificate>
<authentication certificateValidationMode="Custom" customCertificateValidatorType="X509CertificateValidation.CustomValidator, X509CertificateValidation" />
</clientCertificate>
</serviceCredentials>
</behavior>
</serviceBehaviors>
</behaviors>
<protocolMapping>
<add binding="basicHttpsBinding" scheme="https"/>
</protocolMapping>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
</system.serviceModel>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true"/>
<directoryBrowse enabled="true"/>
</system.webServer>
</configuration>
Upvotes: 2
Views: 2153